added rc-style argument GtkSpinButton::shadow_type. removed
authorTim Janik <timj@gtk.org>
Sun, 18 Mar 2001 04:50:34 +0000 (04:50 +0000)
committerTim Janik <timj@src.gnome.org>
Sun, 18 Mar 2001 04:50:34 +0000 (04:50 +0000)
Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>

        * gtk/gtkspinbutton.[hc]: added rc-style argument
        GtkSpinButton::shadow_type.
        removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
        and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
        rc-style settings.

        * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).

        * gtk/gtkwidget.c: quark cleanups.

        * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
        scanner with appropriate configuration, renamed GtkRcStyleClass.clone
        to create_rc_style() (we don't do cloning in standard OO sense).
        added per rc style properties.

        * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
        property values and for caching those. some cleanups.

        * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.

        * gtk/gtksettings.[hc]: new file for global rc-file properties
        (at least currently, should get extended to support X properties
        and other communication mechanisms).

        * gtk/gtkwidget.[hc]: added style property support:
        (gtk_widget_class_install_style_property_parser): install style
        property pspec with parser function for rc-file values other
        than LONG, DOUBLE or STRING.
        (gtk_widget_class_install_style_property): same as above without
        parser (parsers are going to be needed quite infrequently).
        (gtk_widget_style_get_property): retrive style property value.
        (gtk_widget_style_get_valist): same as above with varargs support,
        has NOCOPY semantics.
        (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().

33 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy
docs/reference/gtk/gtk.hierarchy
docs/reference/gtk/tmpl/gtk-unused.sgml
docs/reference/gtk/tmpl/gtksignal.sgml
docs/reference/gtk/tmpl/gtkspinbutton.sgml
docs/reference/gtk/tmpl/gtktextview.sgml
docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml
docs/reference/gtk/tmpl/gtktypeutils.sgml
gtk/Makefile.am
gtk/gtk.h
gtk/gtkcombo.c
gtk/gtkfixed.c
gtk/gtkrc.c
gtk/gtkrc.h
gtk/gtksettings.c [new file with mode: 0644]
gtk/gtksettings.h [new file with mode: 0644]
gtk/gtkspinbutton.c
gtk/gtkspinbutton.h
gtk/gtkstyle.c
gtk/gtkstyle.h
gtk/gtktypeutils.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/testgtkrc
tests/testgtkrc

index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 0bd006cca8006dbf2fe434a0af827e88401c9b78..45b07c33473599c1366559054715608c2b94540b 100644 (file)
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkspinbutton.[hc]: added rc-style argument
+       GtkSpinButton::shadow_type.
+       removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+       and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+       rc-style settings.
+
+       * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+       * gtk/gtkwidget.c: quark cleanups.
+
+       * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+       scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+       to create_rc_style() (we don't do cloning in standard OO sense).
+       added per rc style properties.
+       
+       * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+       property values and for caching those. some cleanups.
+       
+       * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+       
+       * gtk/gtksettings.[hc]: new file for global rc-file properties
+       (at least currently, should get extended to support X properties
+       and other communication mechanisms).
+       
+       * gtk/gtkwidget.[hc]: added style property support:
+       (gtk_widget_class_install_style_property_parser): install style
+       property pspec with parser function for rc-file values other
+       than LONG, DOUBLE or STRING.
+       (gtk_widget_class_install_style_property): same as above without
+       parser (parsers are going to be needed quite infrequently).
+       (gtk_widget_style_get_property): retrive style property value.
+       (gtk_widget_style_get_valist): same as above with varargs support,
+       has NOCOPY semantics.
+       (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
 Fri Mar 16 18:24:53 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * demos/gtk-demo/main.c (row_activated_cb): modified to use
index 3b8038b7dded05e585d642e1e2e29a024a131787..65da5aa3ab9adebf4b4f1b6884586ce22132895c 100644 (file)
@@ -4,5 +4,5 @@ GObject
     GdkDrawableImplX11
       GdkWindowImplX11
   GdkColormap
-  GtkRcStyle
+  GtkSettings
   GdkPixbufLoader
index 0919709543e5d664167365975ae739af4cb8c7ba..4655ff729f25de3db44355d1feaaf4282f4e1ee3 100644 (file)
@@ -5,6 +5,7 @@ GObject
       GdkWindowImplX11
     GdkPixmap
   GdkColormap
+  GtkSettings
   GtkObject
     GtkWidget
       GtkMisc
index ed4abe8fb9253d385c2a5c70d51ceb7ede302f2f..ef1a5fa0cb0cb1ae8e19c77edb2cbe1c6efda692 100644 (file)
@@ -219,6 +219,12 @@ The last structured enumerated type value.
 </para>
 
 
+<!-- ##### MACRO GTK_TYPE_TREE_COLUMN ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### MACRO GTK_VALUE_ARGS ##### -->
 <para>
 Use to get the value of a GtkArg whose GtkType is GTK_TYPE_ARGS
@@ -439,24 +445,6 @@ The position of the cursor.
 </para>
 
 
-<!-- ##### USER_FUNCTION GtkEmissionHook ##### -->
-<para>
-A simple function pointer to get invoked when the
-signal is emitted.  This allows you tie a hook to the signal type,
-so that it will trap all emissions of that signal, from any object.
-</para>
-<para>
-You may not attach these to signals created with the
-#GTK_RUN_NO_HOOKS flag.
-</para>
-
-@object: 
-@signal_id: 
-@n_params: 
-@params: 
-@data: 
-@Returns: 
-
 <!-- ##### ENUM GtkFontFilterType ##### -->
 <para>
 A set of bit flags used to specify the filter being set
@@ -597,6 +585,12 @@ and its unique identifying integer.
 @nparams: 
 @params: 
 
+<!-- ##### ARG GtkSpinButton:shadow-type ##### -->
+<para>
+the type of border that surrounds the arrows of a spin button.
+</para>
+
+
 <!-- ##### STRUCT GtkStatusbarMsg ##### -->
 <para>
 Holds the data for a statusbar message. <structfield>text</structfield> holds the actual text string. <structfield>context_id</structfield> is the context that this message is associated with, and <structfield>message_id</structfield> is this particular message's identifier. However, these fields should not be modified directly.
@@ -633,6 +627,18 @@ produce superscript and subscript.
 </para>
 
 
+<!-- ##### ARG GtkTextView:justify ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkTextView:wrap-mode ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### SIGNAL GtkWidget::debug-msg ##### -->
 <para>
 
@@ -1032,20 +1038,6 @@ Internal function.
 
 @ruler: the gtkruler
 
-<!-- ##### FUNCTION gtk_signal_add_emission_hook ##### -->
-<para>
-Add an emission hook for a type of signal, for any object.
-</para>
-
-@signal_id: the type of signal to hook for.
-@hook_func: the function to invoke to handle the emission hook.
-@data: the user data passed in to hook_func.
-@Returns: the id (that you may pass as a parameter
-to gtk_signal_remove_emission_hook()).
-@i: 
-@h: 
-@d: 
-
 <!-- ##### FUNCTION gtk_signal_add_emission_hook_full ##### -->
 <para>
 Add an emission hook for a type of signal, for any object.
@@ -1085,12 +1077,6 @@ This function is labeled private.
 
 @object: the object whose signal handlers should be destroyed.
 
-<!-- ##### FUNCTION gtk_signal_init ##### -->
-<para>
-
-</para>
-
-
 <!-- ##### FUNCTION gtk_signal_n_emissions ##### -->
 <para>
 Find out the recursion depth of emissions for a particular type
@@ -1132,16 +1118,6 @@ Obtain information about a signal.
 which contains all the information, or NULL.
 The pointer is allocated just for you:  you must g_free() it.
 
-<!-- ##### FUNCTION gtk_signal_remove_emission_hook ##### -->
-<para>
-Delete an emission hook. (see gtk_signal_add_emission_hook())
-</para>
-
-@signal_id: the id of the signal type.
-@hook_id: the id of the emission handler, returned by add_emission_hook().
-@i: 
-@h: 
-
 <!-- ##### FUNCTION gtk_signal_set_funcs ##### -->
 <para>
 These set default functions to call when the user didn't
@@ -1157,6 +1133,14 @@ isn't a function pointer.  May be NULL.
 @destroy_func: the function to invoke when each hook is destroyed.
 May be NULL.
 
+<!-- ##### FUNCTION gtk_spin_button_set_shadow_type ##### -->
+<para>
+Creates a border around the arrows of a #GtkSpinButton. The type of border is determined by @shadow_type.
+</para>
+
+@spin_button: a #GtkSpinButton
+@shadow_type: the new border type.
+
 <!-- ##### FUNCTION gtk_trace_referencing ##### -->
 <para>
 Private: print debugging information while doing a gtk_object_ref() or 
index 1bb805c8ba44b05f829bec5d997406afbab06f7e..11705206fd7abb9fe099a37ca46b684c69c598fd 100644 (file)
@@ -157,6 +157,25 @@ you might have to write a marshaller.
 @field: 
 
 
+<!-- ##### USER_FUNCTION GtkEmissionHook ##### -->
+<para>
+A simple function pointer to get invoked when the
+signal is emitted.  This allows you tie a hook to the signal type,
+so that it will trap all emissions of that signal, from any object.
+</para>
+<para>
+You may not attach these to signals created with the
+#GTK_RUN_NO_HOOKS flag.
+</para>
+
+@object: 
+@signal_id: 
+@n_params: 
+@params: 
+@data: 
+@Returns: 
+
+
 <!-- ##### ENUM GtkSignalRunType ##### -->
 <para>
 These configure the signal's emission.  They control
@@ -232,6 +251,13 @@ to the signal.
 @GTK_RUN_ACTION: 
 @GTK_RUN_NO_HOOKS: 
 
+<!-- ##### FUNCTION gtk_signal_init ##### -->
+<para>
+
+</para>
+
+
+
 <!-- ##### FUNCTION gtk_signal_new ##### -->
 <para>
 Create a new signal type.  (This is usually done in the
@@ -289,7 +315,7 @@ you don't want a return value.
 the callbacks.
 
 
-<!-- ##### MACRO gtk_signal_lookup ##### -->
+<!-- ##### FUNCTION gtk_signal_lookup ##### -->
 <para>
 Given the name of the signal and the type of object it connects
 to, get the signal's identifying integer.  Emitting the signal
@@ -299,13 +325,12 @@ by number is somewhat faster than using the name each time.
 It also tries the ancestors of the given type.
 </para>
 
-@Returns: the signal's identifying number, or 0 if no signal was found.
-<!-- # Unused Parameters # -->
 @name: the signal's name, e.g. clicked.
 @object_type: the type that the signal operates on, e.g. #GTK_TYPE_BUTTON.
+@Returns: the signal's identifying number, or 0 if no signal was found.
 
 
-<!-- ##### MACRO gtk_signal_name ##### -->
+<!-- ##### FUNCTION gtk_signal_name ##### -->
 <para>
 Given the signal's identifier, find its name.
 </para>
@@ -313,9 +338,8 @@ Given the signal's identifier, find its name.
 Two different signals may have the same name, if they have differing types.
 </para>
 
-@Returns: the signal name, or NULL if the signal number was invalid.
-<!-- # Unused Parameters # -->
 @signal_id: the signal's identifying number.
+@Returns: the signal name, or NULL if the signal number was invalid.
 
 
 <!-- ##### FUNCTION gtk_signal_emit ##### -->
@@ -383,7 +407,7 @@ an array of GtkArgs instead of using C's varargs mechanism.
 followed by one which is a pointer to the return type.
 
 
-<!-- ##### MACRO gtk_signal_emit_stop ##### -->
+<!-- ##### FUNCTION gtk_signal_emit_stop ##### -->
 <para>
 This function aborts a signal's current emission.
 </para>
@@ -397,11 +421,11 @@ It will print a warning if used on a signal which
 isn't being emitted.
 </para>
 
-@i: 
-@s: 
-<!-- # Unused Parameters # -->
 @object: the object whose signal handlers you wish to stop.
 @signal_id: the signal identifier, as returned by gtk_signal_lookup().
+<!-- # Unused Parameters # -->
+@i: 
+@s: 
 
 
 <!-- ##### FUNCTION gtk_signal_emit_stop_by_name ##### -->
@@ -417,7 +441,7 @@ except it will lookup the signal id for you.
 @name: the name of the signal you wish to stop.
 
 
-<!-- ##### MACRO gtk_signal_connect ##### -->
+<!-- ##### FUNCTION gtk_signal_connect ##### -->
 <para>
 Attach a function pointer and user data to a signal for
 a particular object.
@@ -456,38 +480,38 @@ static void attach_print_signal(GtkButton* button, gint to_print)
 </programlisting>
 </informalexample>
 
-@o: 
-@s: 
-@f: 
-@d: 
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
 @object: the object associated with the signal, e.g. if a button
 is getting pressed, this is that button.
 @name: name of the signal.
 @func: function pointer to attach to the signal.
 @func_data: value to pass as to your function (through the marshaller).
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o: 
+@s: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_connect_after ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_after ##### -->
 <para>
 Attach a function pointer and user data to a signal
 so that this handler will be called after the other handlers.
 </para>
 
-@o: 
-@s: 
-@f: 
-@d: 
-@Returns: the unique identifier for this attachment:  the connection id.
-<!-- # Unused Parameters # -->
 @object: the object associated with the signal.
 @name: name of the signal.
 @func: function pointer to attach to the signal.
 @func_data: value to pass as to your function (through the marshaller).
+@Returns: the unique identifier for this attachment:  the connection id.
+<!-- # Unused Parameters # -->
+@o: 
+@s: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_connect_object ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_object ##### -->
 <para>
 This function is for registering a callback that will
 call another object's callback.  That is,
@@ -508,21 +532,21 @@ gtk_signal_connect_object(button, "clicked", gtk_widget_show, window);
 </programlisting>
 </informalexample>
 
-@o: 
-@s: 
-@f: 
-@d: 
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal.
 @name: the name of the signal.
 @func: the function to callback.
 @slot_object: the object to pass as the first parameter to func.
 (Though it pretends to take an object, you can
 really pass any gpointer as the #slot_object .)
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o: 
+@s: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_connect_object_after ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_object_after ##### -->
 <para>
 Attach a signal hook to a signal, passing in an alternate
 object as the first parameter, and guaranteeing 
@@ -530,16 +554,16 @@ that the default handler and all normal
 handlers are called first.
 </para>
 
-@o: 
-@s: 
-@f: 
-@d: 
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
 @object: the object associated with the signal.
 @name: name of the signal.
 @func: function pointer to attach to the signal.
 @slot_object: the object to pass as the first parameter to #func.
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o: 
+@s: 
+@f: 
+@d: 
 
 
 <!-- ##### FUNCTION gtk_signal_connect_full ##### -->
@@ -628,98 +652,95 @@ should signal the removal of this signal.
 @name: name of the signal.
 
 
-<!-- ##### MACRO gtk_signal_disconnect ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect ##### -->
 <para>
 Destroy a user-defined handler connection.
 </para>
 
-<!-- # Unused Parameters # -->
 @object: the object which the handler pertains to.
 @handler_id: the connection id.
 
 
-<!-- ##### MACRO gtk_signal_disconnect_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect_by_func ##### -->
 <para>
 Destroy all connections for a particular object, with
 the given function-pointer and user-data.
 </para>
 
-@o: 
-@f: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal.
 @func: the function pointer to search for.
 @data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_disconnect_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect_by_data ##### -->
 <para>
 Destroy all connections for a particular object, with
 the given user-data.
 </para>
 
-@o: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal.
 @data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_handler_block ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block ##### -->
 <para>
 Prevent an user-defined handler from being invoked.  All other
 signal processing will go on as normal, but this particular
 handler will ignore it.
 </para>
 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal to block.
 @handler_id: the connection id.
 
 
-<!-- ##### MACRO gtk_signal_handler_block_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block_by_func ##### -->
 <para>
 Prevent a user-defined handler from being invoked, by reference to
 the user-defined handler's function pointer and user data.  (It may result in
 multiple hooks being blocked, if you've called connect multiple times.)
 </para>
 
-@o: 
-@f: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal to block.
 @func: the function pointer of the handler to block.
 @data: the user data of the handler to block.
+<!-- # Unused Parameters # -->
+@o: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_handler_block_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block_by_data ##### -->
 <para>
 Prevent all user-defined handlers with a certain user data from being invoked.
 </para>
 
-@o: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal we want to block.
 @data: the user data of the handlers to block.
+<!-- # Unused Parameters # -->
+@o: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_handler_unblock ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock ##### -->
 <para>
 Undo a block, by connection id.  Note that undoing a block doesn't
 necessarily make the hook callable, because if you block a
 hook twice, you must unblock it twice.
 </para>
 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal we want to unblock.
 @handler_id: the emission handler identifier, as returned by
 gtk_signal_connect(), etc.
 
 
-<!-- ##### MACRO gtk_signal_handler_unblock_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock_by_func ##### -->
 <para>
 Undo a block, by function pointer and data.
 Note that undoing a block doesn't
@@ -727,29 +748,29 @@ necessarily make the hook callable, because if you block a
 hook twice, you must unblock it twice.
 </para>
 
-@o: 
-@f: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal we want to unblock.
 @func: the function pointer to search for.
 @data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o: 
+@f: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_handler_unblock_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock_by_data ##### -->
 <para>
 Undo block(s), to all signals for a particular object
 with a particular user-data pointer
 </para>
 
-@o: 
-@d: 
-<!-- # Unused Parameters # -->
 @object: the object which emits the signal we want to unblock.
 @data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o: 
+@d: 
 
 
-<!-- ##### MACRO gtk_signal_handler_pending ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_pending ##### -->
 <para>
 Returns a connection id corresponding to a given signal id and object.
 </para>
@@ -760,36 +781,64 @@ may opt to not emit the signal if no one is attached anyway,
 thus saving the cost of building the arguments.
 </para>
 
-@i: 
-@s: 
-@b: 
-@Returns: the connection id, if a connection was found.  0 otherwise.
-<!-- # Unused Parameters # -->
 @object: the object to search for the desired user-defined handler.
 @signal_id: the number of the signal to search for.
 @may_be_blocked: whether it is acceptable to return a blocked
 handler.
+@Returns: the connection id, if a connection was found.  0 otherwise.
+<!-- # Unused Parameters # -->
+@i: 
+@s: 
+@b: 
 
 
-<!-- ##### MACRO gtk_signal_handler_pending_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_pending_by_func ##### -->
 <para>
 Returns a connection id corresponding to a given signal id, object, function
 pointer and user data.
 </para>
 
-@o: 
-@s: 
-@b: 
-@f: 
-@d: 
-@Returns: the connection id, if a handler was found.  0 otherwise.
-<!-- # Unused Parameters # -->
 @object: the object to search for the desired handler.
 @signal_id: the number of the signal to search for.
 @may_be_blocked: whether it is acceptable to return a blocked
 handler.
 @func: the function pointer to search for.
 @data: the user data to search for.
+@Returns: the connection id, if a handler was found.  0 otherwise.
+<!-- # Unused Parameters # -->
+@o: 
+@s: 
+@b: 
+@f: 
+@d: 
+
+
+<!-- ##### FUNCTION gtk_signal_add_emission_hook ##### -->
+<para>
+Add an emission hook for a type of signal, for any object.
+</para>
+
+@signal_id: the type of signal to hook for.
+@hook_func: the function to invoke to handle the emission hook.
+@data: the user data passed in to hook_func.
+@Returns: the id (that you may pass as a parameter
+to gtk_signal_remove_emission_hook()).
+<!-- # Unused Parameters # -->
+@i: 
+@h: 
+@d: 
+
+
+<!-- ##### FUNCTION gtk_signal_remove_emission_hook ##### -->
+<para>
+Delete an emission hook. (see gtk_signal_add_emission_hook())
+</para>
+
+@signal_id: the id of the signal type.
+@hook_id: the id of the emission handler, returned by add_emission_hook().
+<!-- # Unused Parameters # -->
+@i: 
+@h: 
 
 
 <!-- ##### MACRO gtk_signal_default_marshaller ##### -->
index 7b28651e4a9dfa0e9a6e55840260a74dd1011831..8e82038d75732172372a018c2bee9f06a78c962d 100644 (file)
@@ -294,15 +294,6 @@ Sets a spin button's value to the lower limit when it's upper limit is reached,
 @wrap: defaults to FALSE, set to TRUE to make the spin button wrap.
 
 
-<!-- ##### FUNCTION gtk_spin_button_set_shadow_type ##### -->
-<para>
-Creates a border around the arrows of a #GtkSpinButton. The type of border is determined by @shadow_type.
-</para>
-
-@spin_button: a #GtkSpinButton
-@shadow_type: the new border type.
-
-
 <!-- ##### FUNCTION gtk_spin_button_set_snap_to_ticks ##### -->
 <para>
 Sets whether a number typed into a spin button should be snapped to the nearest step increment.
@@ -379,11 +370,6 @@ whether a spin button should wrap upon reaching its limits.
 how a spin button should be updated.
 </para>
 
-<!-- ##### ARG GtkSpinButton:shadow-type ##### -->
-<para>
-the type of border that surrounds the arrows of a spin button.
-</para>
-
 <!-- ##### ARG GtkSpinButton:value ##### -->
 <para>
 reads the current value, or sets a new value.
index 0f5962ed0ce885f6a230b818bfb60cad8303d74b..5d07a0e65cb91b47eef4bc6047c75539a5d02470 100644 (file)
@@ -631,16 +631,6 @@ types related to the text widget and how they work together.
 
 </para>
 
-<!-- ##### ARG GtkTextView:wrap-mode ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkTextView:justify ##### -->
-<para>
-
-</para>
-
 <!-- ##### ARG GtkTextView:left-margin ##### -->
 <para>
 
index d813c35ada5f20df554d4a525b1826de6475d918..23d8a438785609e348cdb63e8dc73d2fc13644c0 100644 (file)
@@ -14,13 +14,6 @@ GtkTreeViewColumn
 
 </para>
 
-<!-- ##### MACRO GTK_TYPE_TREE_COLUMN ##### -->
-<para>
-
-</para>
-
-
-
 <!-- ##### STRUCT GtkTreeViewColumn ##### -->
 <para>
 
index 16a7e543fe3c07d2d2f92ae550b3b72848fe61cb..6295e2dfa13c7a3966a7f8539ef3509ca5119ff6 100644 (file)
@@ -560,33 +560,30 @@ Create a new, unique type.
 @type_info: must not be null, and @type_info->type_name must also not be null.
 
 
-<!-- ##### MACRO gtk_type_name ##### -->
+<!-- ##### FUNCTION gtk_type_name ##### -->
 <para>
 </para>
 
-@Returns: a pointer to the name of a type, or NULL if it has none.
-<!-- # Unused Parameters # -->
 @type: a GtkType
+@Returns: a pointer to the name of a type, or NULL if it has none.
 
 
-<!-- ##### MACRO gtk_type_from_name ##### -->
+<!-- ##### FUNCTION gtk_type_from_name ##### -->
 <para>
 Get the internal representation of a type given its name.
 </para>
 
-@Returns: a GtkType
-<!-- # Unused Parameters # -->
 @name: the name of a gtk type
+@Returns: a GtkType
 
 
-<!-- ##### MACRO gtk_type_parent ##### -->
+<!-- ##### FUNCTION gtk_type_parent ##### -->
 <para>
 
 </para>
 
-@Returns: the GtkType of the parent
-<!-- # Unused Parameters # -->
 @type: a GtkType
+@Returns: the GtkType of the parent
 
 
 <!-- ##### FUNCTION gtk_type_class ##### -->
@@ -611,16 +608,15 @@ has all the proper initializers called.
 @Returns: gpointer to a GtkTypeObject
 
 
-<!-- ##### MACRO gtk_type_is_a ##### -->
+<!-- ##### FUNCTION gtk_type_is_a ##### -->
 <para>
 Look in the type hierarchy to see if @type has @is_a_type among its
 ancestors.  Do so with a simple lookup, not a loop.
 </para>
 
-@Returns: 
-<!-- # Unused Parameters # -->
 @type: GtkType
 @is_a_type: GtkType
+@Returns: 
 
 
 <!-- ##### FUNCTION gtk_type_enum_get_values ##### -->
index 623759da913768f3f17c98017cd29187f2753d94..a33192e88425152d88e6e6ecc03e29858b70f50c 100644 (file)
@@ -11,6 +11,7 @@ INCLUDES = @STRIP_BEGIN@ \
        -DGTK_LOCALEDIR=\"$(gtklocaledir)\"             \
        -DGTK_VERSION=\"@GTK_VERSION@\"                 \
        -DTESTGTK_RCFILE=\"`pwd`/$(srcdir)/testgtkrc\"  \
+       -DG_DISABLE_CONST_RETURNS                       \
        -I$(top_builddir)/gtk                           \
        -I$(top_srcdir) -I../gdk                        \
        -I$(top_srcdir)/gdk                             \
@@ -147,6 +148,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
        gtkscrolledwindow.h     \
        gtkselection.h          \
        gtkseparator.h          \
+       gtksettings.h           \
        gtksignal.h             \
        gtksocket.h             \
        gtkspinbutton.h         \
@@ -306,6 +308,7 @@ gtk_c_sources = @STRIP_BEGIN@   \
        gtkscrolledwindow.c     \
        gtkselection.c          \
        gtkseparator.c          \
+       gtksettings.c           \
        gtksignal.c             \
        gtksocket.c             \
        gtkspinbutton.c         \
index c1df20b2adbbb73cc7306311a7a7ec95c174c93d..e762c68df9def7a6b4f7ca22d4d08b3fb6d96d86 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
 #include <gtk/gtkselection.h>
 #include <gtk/gtkseparator.h>
 #include <gtk/gtkseparatormenuitem.h>
+#include <gtk/gtksettings.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtksocket.h>
 #include <gtk/gtkspinbutton.h>
index 706692e76713f884f7ef8f0f46b54b838aa1a868..be607894ce9f4af7f7f67f2d755d9ea7e8cde6a1 100644 (file)
@@ -259,8 +259,6 @@ gtk_combo_window_key_press (GtkWidget   *window,
                            GdkEventKey *event,
                            GtkCombo    *combo)
 {
-  GList *li;
-
   if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
     {
       if (GTK_WIDGET_VISIBLE (combo->popwin))
index 9380399439232b1e5830b0b02ede602e93537a45..ab1bffceae8d23577453ba2988136e35308d9ae4 100644 (file)
@@ -35,8 +35,6 @@ static void gtk_fixed_size_request  (GtkWidget        *widget,
                                     GtkRequisition   *requisition);
 static void gtk_fixed_size_allocate (GtkWidget        *widget,
                                     GtkAllocation    *allocation);
-static void gtk_fixed_paint         (GtkWidget        *widget,
-                                    GdkRectangle     *area);
 static void gtk_fixed_add           (GtkContainer     *container,
                                     GtkWidget        *widget);
 static void gtk_fixed_remove        (GtkContainer     *container,
@@ -332,20 +330,6 @@ gtk_fixed_size_allocate (GtkWidget     *widget,
     }
 }
 
-static void
-gtk_fixed_paint (GtkWidget    *widget,
-                GdkRectangle *area)
-{
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_FIXED (widget));
-  g_return_if_fail (area != NULL);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    gdk_window_clear_area (widget->window,
-                          area->x, area->y,
-                          area->width, area->height);
-}
-
 static void
 gtk_fixed_add (GtkContainer *container,
               GtkWidget    *widget)
index 069cc4e22216a4c4c184699c98b457a4d0a6dd84..de18328b6ee19032aa5377ed2cd556bffc3bc86d 100644 (file)
@@ -57,6 +57,7 @@
 #include "gtkthemes.h"
 #include "gtkintl.h"
 #include "gtkiconfactory.h"
+#include "gtksettings.h"
 
 #ifdef G_OS_WIN32
 #include <io.h>
@@ -101,6 +102,8 @@ static void        gtk_rc_parse_any                  (const gchar     *input_nam
                                                       const gchar     *input_string);
 static guint       gtk_rc_parse_statement            (GScanner        *scanner);
 static guint       gtk_rc_parse_style                (GScanner        *scanner);
+static guint       gtk_rc_parse_assignment           (GScanner        *scanner,
+                                                     GtkRcProperty   *prop);
 static guint       gtk_rc_parse_bg                   (GScanner        *scanner,
                                                       GtkRcStyle      *style);
 static guint       gtk_rc_parse_fg                   (GScanner        *scanner,
@@ -145,12 +148,14 @@ static void        gtk_rc_style_class_init           (GtkRcStyleClass *klass);
 static void        gtk_rc_style_finalize             (GObject         *object);
 static void        gtk_rc_style_real_merge           (GtkRcStyle      *dest,
                                                       GtkRcStyle      *src);
-static GtkRcStyle *gtk_rc_style_real_clone           (GtkRcStyle      *rc_style);
-static GtkStyle *  gtk_rc_style_real_create_style    (GtkRcStyle      *rc_style);
+static GtkRcStyle* gtk_rc_style_real_create_rc_style (GtkRcStyle      *rc_style);
+static GtkStyle*   gtk_rc_style_real_create_style    (GtkRcStyle      *rc_style);
+static gint       gtk_rc_properties_cmp             (gconstpointer    bsearch_node1,
+                                                     gconstpointer    bsearch_node2);
 
 static gpointer parent_class = NULL;
 
-static const GScannerConfig  gtk_rc_scanner_config =
+static const GScannerConfig gtk_rc_scanner_config =
 {
   (
    " \t\r\n"
@@ -267,7 +272,6 @@ static GtkImageLoader image_loader = NULL;
 
 
 #ifdef G_OS_WIN32
-
 static gchar *
 get_gtk_dll_name (void)
 {
@@ -286,8 +290,7 @@ get_themes_directory (void)
                                                        get_gtk_dll_name (),
                                                        "themes");
 }
-
-#endif
+#endif /* G_OS_WIN32 */
  
 static gchar *
 gtk_rc_make_default_dir (const gchar *type)
@@ -563,12 +566,11 @@ gtk_rc_get_default_files (void)
 void
 gtk_rc_init (void)
 {
+  static gboolean initialized = FALSE;
   static gchar *locale_suffixes[3];
   static gint n_locale_suffixes = 0;
-
   gint i, j;
 
-  static gboolean initialized = FALSE;
 
   if (!initialized)
     {
@@ -631,13 +633,13 @@ gtk_rc_init (void)
        }
     }
   
-  i = 0;
-  while (gtk_rc_default_files[i] != NULL)
+  g_object_freeze_notify (G_OBJECT (gtk_settings_get_global ()));
+  for (i = 0; gtk_rc_default_files[i] != NULL; i++)
     {
-      /* Try to find a locale specific RC file corresponding to
-       * to parse before the default file.
+      /* Try to find a locale specific RC file corresponding to the
+       * current locale to parse before the default file.
        */
-      for (j=n_locale_suffixes-1; j>=0; j--)
+      for (j = n_locale_suffixes - 1; j >= 0; j--)
        {
          gchar *name = g_strconcat (gtk_rc_default_files[i],
                                     ".",
@@ -646,10 +648,9 @@ gtk_rc_init (void)
          gtk_rc_parse (name);
          g_free (name);
        }
-
       gtk_rc_parse (gtk_rc_default_files[i]);
-      i++;
     }
+  g_object_thaw_notify (G_OBJECT (gtk_settings_get_global ()));
 }
 
 void
@@ -801,6 +802,7 @@ gtk_rc_style_init (GtkRcStyle *style)
     }
   style->xthickness = -1;
   style->ythickness = -1;
+  style->rc_properties = NULL;
 
   style->rc_style_lists = NULL;
   style->icon_factories = NULL;
@@ -816,55 +818,17 @@ gtk_rc_style_class_init (GtkRcStyleClass *klass)
   object_class->finalize = gtk_rc_style_finalize;
 
   klass->parse = NULL;
-  klass->clone = gtk_rc_style_real_clone;
+  klass->create_rc_style = gtk_rc_style_real_create_rc_style;
   klass->merge = gtk_rc_style_real_merge;
   klass->create_style = gtk_rc_style_real_create_style;
 }
 
-/* Like g_slist_remove, but remove all copies of data */
-static GSList *
-gtk_rc_slist_remove_all (GSList   *list,
-                        gpointer  data)
-{
-  GSList *tmp;
-  GSList *prev;
-
-  prev = NULL;
-  tmp = list;
-
-  while (tmp)
-    {
-      if (tmp->data == data)
-       {
-         if (list == tmp)
-           list = list->next;
-
-         if (prev) 
-           prev->next = tmp->next;
-
-         g_slist_free_1 (tmp);
-
-         if (prev)
-           tmp = prev->next;
-         else
-           tmp = list;
-       }
-      else
-       {
-         prev = tmp;
-         tmp = tmp->next;
-       }
-    }
-
-  return list;
-}
-
 static void
 gtk_rc_style_finalize (GObject *object)
 {
-  gint i;
   GSList *tmp_list1, *tmp_list2;
   GtkRcStyle *rc_style;
+  gint i;
 
   rc_style = GTK_RC_STYLE (object);
   
@@ -873,7 +837,7 @@ gtk_rc_style_finalize (GObject *object)
   if (rc_style->font_desc)
     pango_font_description_free (rc_style->font_desc);
       
-  for (i=0 ; i < 5 ; i++)
+  for (i = 0; i < 5; i++)
     if (rc_style->bg_pixmap_name[i])
       g_free (rc_style->bg_pixmap_name[i]);
   
@@ -896,9 +860,8 @@ gtk_rc_style_finalize (GObject *object)
           GtkRcStyle *other_style = tmp_list2->data;
 
           if (other_style != rc_style)
-            other_style->rc_style_lists =
-              gtk_rc_slist_remove_all (other_style->rc_style_lists, rc_styles);
-                 
+            other_style->rc_style_lists = g_slist_remove_all (other_style->rc_style_lists,
+                                                             rc_styles);
           tmp_list2 = tmp_list2->next;
         }
 
@@ -909,9 +872,23 @@ gtk_rc_style_finalize (GObject *object)
 
       tmp_list1 = tmp_list1->next;
     }
-
   g_slist_free (rc_style->rc_style_lists);
 
+  if (rc_style->rc_properties)
+    {
+      guint i;
+
+      for (i = 0; i < rc_style->rc_properties->n_nodes; i++)
+       {
+         GtkRcProperty *node = g_bsearch_array_get_nth (rc_style->rc_properties, i);
+
+         g_free (node->origin);
+         g_value_unset (&node->value);
+       }
+      g_bsearch_array_destroy (rc_style->rc_properties);
+      rc_style->rc_properties = NULL;
+    }
+
   tmp_list1 = rc_style->icon_factories;
   while (tmp_list1)
     {
@@ -919,7 +896,6 @@ gtk_rc_style_finalize (GObject *object)
 
       tmp_list1 = tmp_list1->next;
     }
-
   g_slist_free (rc_style->icon_factories);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -952,7 +928,7 @@ gtk_rc_style_copy (GtkRcStyle *orig)
 
   g_return_val_if_fail (GTK_IS_RC_STYLE (orig), NULL);
   
-  style = GTK_RC_STYLE_GET_CLASS (orig)->clone (orig);
+  style = GTK_RC_STYLE_GET_CLASS (orig)->create_rc_style (orig);
   GTK_RC_STYLE_GET_CLASS (style)->merge (style, orig);
 
   return style;
@@ -975,11 +951,26 @@ gtk_rc_style_unref (GtkRcStyle  *rc_style)
 }
 
 static GtkRcStyle *
-gtk_rc_style_real_clone (GtkRcStyle *style)
+gtk_rc_style_real_create_rc_style (GtkRcStyle *style)
 {
   return GTK_RC_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
 }
 
+static gint
+gtk_rc_properties_cmp (gconstpointer bsearch_node1,
+                      gconstpointer bsearch_node2)
+{
+  const GtkRcProperty *prop1 = bsearch_node1;
+  const GtkRcProperty *prop2 = bsearch_node2;
+  gint cmp;
+
+  cmp = G_BSEARCH_ARRAY_CMP (prop1->type_name, prop2->type_name);
+  if (cmp == 0)
+    cmp = G_BSEARCH_ARRAY_CMP (prop1->property_name, prop2->property_name);
+
+  return cmp;
+}
+
 static void
 gtk_rc_style_real_merge (GtkRcStyle *dest,
                         GtkRcStyle *src)
@@ -1024,6 +1015,31 @@ gtk_rc_style_real_merge (GtkRcStyle *dest,
 
   if (!dest->font_desc && src->font_desc)
     dest->font_desc = pango_font_description_copy (src->font_desc);
+
+  if (src->rc_properties)
+    {
+      guint i;
+
+      if (!dest->rc_properties)
+       dest->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+                                                  gtk_rc_properties_cmp,
+                                                  0);
+      for (i = 0; i < src->rc_properties->n_nodes; i++)
+       {
+         GtkRcProperty *node = g_bsearch_array_get_nth (src->rc_properties, i);
+         GtkRcProperty *prop, key = { 0, 0, NULL, { 0, }, };
+
+         key.type_name = node->type_name;
+         key.property_name = node->property_name;
+         prop = g_bsearch_array_insert (dest->rc_properties, &key, FALSE);
+         if (!prop->origin)
+           {
+             prop->origin = g_strdup (node->origin);
+             g_value_init (&prop->value, G_VALUE_TYPE (&node->value));
+             g_value_copy (&node->value, &prop->value);
+           }
+       }
+    }
 }
 
 static GtkStyle *
@@ -1274,6 +1290,12 @@ gtk_rc_add_class_style (GtkRcStyle  *rc_style,
   gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
 }
 
+GScanner*
+gtk_rc_scanner_new (void)
+{
+  return g_scanner_new (&gtk_rc_scanner_config);
+}
+
 static void
 gtk_rc_parse_any (const gchar  *input_name,
                  gint          input_fd,
@@ -1282,8 +1304,8 @@ gtk_rc_parse_any (const gchar  *input_name,
   GScanner *scanner;
   guint           i;
   gboolean done;
-  
-  scanner = g_scanner_new ((GScannerConfig *) &gtk_rc_scanner_config);
+
+  scanner = gtk_rc_scanner_new ();
   
   if (input_fd >= 0)
     {
@@ -1478,7 +1500,7 @@ gtk_rc_init_style (GSList *rc_styles)
        }
       
       proto_style_class = GTK_RC_STYLE_GET_CLASS (base_style);
-      proto_style = proto_style_class->clone (base_style);
+      proto_style = proto_style_class->create_rc_style (base_style);
       
       tmp_styles = rc_styles;
       while (tmp_styles)
@@ -1535,24 +1557,205 @@ gtk_rc_init_style (GSList *rc_styles)
  * Parsing functions *
  *********************/
 
+static guint
+rc_parse_token_or_compound (GScanner  *scanner,
+                           GString   *gstring,
+                           GTokenType delimiter)
+{
+  guint token = g_scanner_get_next_token (scanner);
+
+  /* we either scan a single token (skipping comments)
+   * or a compund statement.
+   * compunds are enclosed in (), [] or {} braces, we read
+   * them in via deep recursion.
+   */
+
+  switch (token)
+    {
+      gchar *string;
+    case G_TOKEN_INT:
+      g_string_printfa (gstring, " 0x%lx", scanner->value.v_int);
+      break;
+    case G_TOKEN_FLOAT:
+      g_string_printfa (gstring, " %f", scanner->value.v_float);
+      break;
+    case G_TOKEN_STRING:
+      string = g_strescape (scanner->value.v_string, NULL);
+      g_string_append (gstring, " \"");
+      g_string_append (gstring, string);
+      g_string_append_c (gstring, '"');
+      g_free (string);
+      break;
+    case G_TOKEN_IDENTIFIER:
+      g_string_append_c (gstring, ' ');
+      g_string_append (gstring, scanner->value.v_identifier);
+      break;
+    case G_TOKEN_COMMENT_SINGLE:
+    case G_TOKEN_COMMENT_MULTI:
+      return rc_parse_token_or_compound (scanner, gstring, delimiter);
+    case G_TOKEN_LEFT_PAREN:
+      g_string_append_c (gstring, ' ');
+      g_string_append_c (gstring, token);
+      token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_PAREN);
+      if (token != G_TOKEN_NONE)
+       return token;
+      break;
+    case G_TOKEN_LEFT_CURLY:
+      g_string_append_c (gstring, ' ');
+      g_string_append_c (gstring, token);
+      token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_CURLY);
+      if (token != G_TOKEN_NONE)
+       return token;
+      break;
+    case G_TOKEN_LEFT_BRACE:
+      g_string_append_c (gstring, ' ');
+      g_string_append_c (gstring, token);
+      token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_BRACE);
+      if (token != G_TOKEN_NONE)
+       return token;
+      break;
+    default:
+      if (token >= 256 || token < 1)
+       return delimiter ? delimiter : G_TOKEN_STRING;
+      g_string_append_c (gstring, ' ');
+      g_string_append_c (gstring, token);
+      if (token == delimiter)
+       return G_TOKEN_NONE;
+      break;
+    }
+  if (!delimiter)
+    return G_TOKEN_NONE;
+  else
+    return rc_parse_token_or_compound (scanner, gstring, delimiter);
+}
+
+static guint
+gtk_rc_parse_assignment (GScanner      *scanner,
+                        GtkRcProperty *prop)
+{
+  gboolean scan_identifier = scanner->config->scan_identifier;
+  gboolean scan_symbols = scanner->config->scan_symbols;
+  gboolean identifier_2_string = scanner->config->identifier_2_string;
+  gboolean char_2_token = scanner->config->char_2_token;
+  gboolean scan_identifier_NULL = scanner->config->scan_identifier_NULL;
+  gboolean numbers_2_int = scanner->config->numbers_2_int;
+  gboolean negate = FALSE;
+  guint token;
+
+  /* check that this is an assignment */
+  if (g_scanner_get_next_token (scanner) != '=')
+    return '=';
+
+  /* adjust scanner mode */
+  scanner->config->scan_identifier = TRUE;
+  scanner->config->scan_symbols = FALSE;
+  scanner->config->identifier_2_string = FALSE;
+  scanner->config->char_2_token = TRUE;
+  scanner->config->scan_identifier_NULL = FALSE;
+  scanner->config->numbers_2_int = TRUE;
+
+  /* record location */
+  prop->origin = g_strdup_printf ("%s:%u", scanner->input_name, scanner->line);
+
+  /* parse optional sign */
+  if (g_scanner_peek_next_token (scanner) == '-')
+    {
+      g_scanner_get_next_token (scanner); /* eat sign */
+      negate = TRUE;
+    }
+
+  /* parse one of LONG, DOUBLE and STRING or, if that fails, create an unparsed compund */
+  token = g_scanner_peek_next_token (scanner);
+  switch (token)
+    {
+    case G_TOKEN_INT:
+      g_scanner_get_next_token (scanner);
+      g_value_init (&prop->value, G_TYPE_LONG);
+      g_value_set_long (&prop->value, negate ? -scanner->value.v_int : scanner->value.v_int);
+      token = G_TOKEN_NONE;
+      break;
+    case G_TOKEN_FLOAT:
+      g_scanner_get_next_token (scanner);
+      g_value_init (&prop->value, G_TYPE_DOUBLE);
+      g_value_set_double (&prop->value, negate ? -scanner->value.v_float : scanner->value.v_float);
+      token = G_TOKEN_NONE;
+      break;
+    case G_TOKEN_STRING:
+      g_scanner_get_next_token (scanner);
+      if (negate)
+       token = G_TOKEN_INT;
+      else
+       {
+         g_value_init (&prop->value, G_TYPE_STRING);
+         g_value_set_string (&prop->value, scanner->value.v_string);
+         token = G_TOKEN_NONE;
+       }
+      break;
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_LEFT_PAREN:
+    case G_TOKEN_LEFT_CURLY:
+    case G_TOKEN_LEFT_BRACE:
+      if (!negate)
+       {
+         GString *gstring = g_string_new ("");
+
+         token = rc_parse_token_or_compound (scanner, gstring, 0);
+         if (token == G_TOKEN_NONE)
+           {
+             g_string_append_c (gstring, ' ');
+             g_value_init (&prop->value, G_TYPE_GSTRING);
+             g_value_set_static_boxed (&prop->value, gstring);
+           }
+         else
+           g_string_free (gstring, TRUE);
+         break;
+       }
+      /* fall through */
+    default:
+      g_scanner_get_next_token (scanner);
+      token = G_TOKEN_INT;
+      break;
+    }
+
+  /* restore scanner mode */
+  scanner->config->scan_identifier = scan_identifier;
+  scanner->config->scan_symbols = scan_symbols;
+  scanner->config->identifier_2_string = identifier_2_string;
+  scanner->config->char_2_token = char_2_token;
+  scanner->config->scan_identifier_NULL = scan_identifier_NULL;
+  scanner->config->numbers_2_int = numbers_2_int;
+
+  return token;
+}
+
+static gboolean
+is_c_identifier (const gchar *string)
+{
+  const gchar *p;
+  gboolean is_varname;
+
+  is_varname = strchr (G_CSET_a_2_z G_CSET_A_2_Z "_", string[0]) != NULL;
+  for (p = string + 1; *p && is_varname; p++)
+    is_varname &= strchr (G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "_-", *p) != NULL;
+
+  return is_varname;
+}
+
 static guint
 gtk_rc_parse_statement (GScanner *scanner)
 {
   guint token;
   
   token = g_scanner_peek_next_token (scanner);
-  
   switch (token)
     {
     case GTK_RC_TOKEN_INCLUDE:
       token = g_scanner_get_next_token (scanner);
       if (token != GTK_RC_TOKEN_INCLUDE)
        return GTK_RC_TOKEN_INCLUDE;
-      
       token = g_scanner_get_next_token (scanner);
       if (token != G_TOKEN_STRING)
        return G_TOKEN_STRING;
-      
       gtk_rc_parse_file (scanner->value.v_string, FALSE);
       return G_TOKEN_NONE;
       
@@ -1583,6 +1786,39 @@ gtk_rc_parse_statement (GScanner *scanner)
     case GTK_RC_TOKEN_IM_MODULE_FILE:
       return gtk_rc_parse_im_module_file (scanner);
 
+    case G_TOKEN_IDENTIFIER:
+      if (is_c_identifier (scanner->next_value.v_identifier))
+       {
+         GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
+         gchar *name;
+         
+         g_scanner_get_next_token (scanner); /* eat identifier */
+         name = g_strdup (scanner->value.v_identifier);
+         
+         token = gtk_rc_parse_assignment (scanner, &prop);
+         if (token == G_TOKEN_NONE)
+           {
+             GtkSettingsValue svalue;
+
+             svalue.origin = prop.origin;
+             memcpy (&svalue.value, &prop.value, sizeof (prop.value));
+             g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+             gtk_settings_set_property_value (gtk_settings_get_global (),
+                                              name,
+                                              &svalue);
+           }
+         g_free (prop.origin);
+         if (G_VALUE_TYPE (&prop.value))
+           g_value_unset (&prop.value);
+         g_free (name);
+         
+         return token;
+       }
+      else
+       {
+         g_scanner_get_next_token (scanner);
+         return G_TOKEN_IDENTIFIER;
+       }
     default:
       g_scanner_get_next_token (scanner);
       return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
@@ -1666,6 +1902,33 @@ gtk_rc_parse_style (GScanner *scanner)
                pango_font_description_free (rc_style->font_desc);
              rc_style->font_desc = pango_font_description_copy (parent_style->font_desc);
            }
+
+         if (parent_style->rc_properties)
+           {
+             guint i;
+
+             if (!rc_style->rc_properties)
+               rc_style->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+                                                              gtk_rc_properties_cmp,
+                                                              0);
+             for (i = 0; i < parent_style->rc_properties->n_nodes; i++)
+               {
+                 GtkRcProperty *node = g_bsearch_array_get_nth (parent_style->rc_properties, i);
+                 GtkRcProperty *prop, key = { 0, 0, NULL, { 0, }, };
+
+                 key.type_name = node->type_name;
+                 key.property_name = node->property_name;
+                 prop = g_bsearch_array_insert (rc_style->rc_properties, &key, FALSE);
+                 if (prop->origin)
+                   {
+                     g_free (prop->origin);
+                     g_value_unset (&prop->value);
+                   }
+                 prop->origin = g_strdup (node->origin);
+                 g_value_init (&prop->value, G_VALUE_TYPE (&node->value));
+                 g_value_copy (&node->value, &prop->value);
+               }
+           }
          
          for (i = 0; i < 5; i++)
            {
@@ -1761,6 +2024,65 @@ gtk_rc_parse_style (GScanner *scanner)
             }
           token = gtk_rc_parse_stock (scanner, rc_style, our_factory);
           break;
+       case G_TOKEN_IDENTIFIER:
+         if (is_c_identifier (scanner->next_value.v_identifier) &&
+             scanner->next_value.v_identifier[0] >= 'A' &&
+             scanner->next_value.v_identifier[0] <= 'Z') /* match namespaced type names */
+           {
+             GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
+             
+             g_scanner_get_next_token (scanner); /* eat type name */
+             prop.type_name = g_quark_from_string (scanner->value.v_identifier);
+             if (g_scanner_get_next_token (scanner) != ':' ||
+                 g_scanner_get_next_token (scanner) != ':')
+               {
+                 token = ':';
+                 break;
+               }
+             if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER ||
+                 !is_c_identifier (scanner->value.v_identifier))
+               {
+                 token = G_TOKEN_IDENTIFIER;
+                 break;
+               }
+
+             /* it's important that we do the same canonification as GParamSpecPool here */
+             g_strcanon (scanner->value.v_identifier, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+             prop.property_name = g_quark_from_string (scanner->value.v_identifier);
+
+             token = gtk_rc_parse_assignment (scanner, &prop);
+             if (token == G_TOKEN_NONE)
+               {
+                 GtkRcProperty *tmp;
+
+                 g_return_val_if_fail (prop.origin != NULL && G_VALUE_TYPE (&prop.value) != 0, G_TOKEN_ERROR);
+
+                 if (!rc_style->rc_properties)
+                   rc_style->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+                                                                  gtk_rc_properties_cmp,
+                                                                  0);
+                 tmp = g_bsearch_array_insert (rc_style->rc_properties, &prop, FALSE);
+                 if (prop.origin != tmp->origin)
+                   {
+                     g_free (tmp->origin);
+                     g_value_unset (&tmp->value);
+                     tmp->origin = prop.origin;
+                     memcpy (&tmp->value, &prop.value, sizeof (prop.value));
+                   }
+               }
+             else
+               {
+                 g_free (prop.origin);
+                 if (G_VALUE_TYPE (&prop.value))
+                   g_value_unset (&prop.value);
+               }
+           }
+         else
+           {
+             g_scanner_get_next_token (scanner);
+             token = G_TOKEN_IDENTIFIER;
+           }
+         break;
        default:
          g_scanner_get_next_token (scanner);
          token = G_TOKEN_RIGHT_CURLY;
@@ -1770,19 +2092,12 @@ gtk_rc_parse_style (GScanner *scanner)
       if (token != G_TOKEN_NONE)
        {
          if (insert)
-           {
-             if (rc_style->font_desc)
-               pango_font_description_free (rc_style->font_desc);
-             
-             for (i = 0; i < 5; i++)
-               if (rc_style->bg_pixmap_name[i])
-                 g_free (rc_style->bg_pixmap_name[i]);
-             g_free (rc_style);
-           }
+           gtk_rc_style_unref (rc_style);
+
          return token;
        }
       token = g_scanner_peek_next_token (scanner);
-    }
+    } /* while (token != G_TOKEN_RIGHT_CURLY) */
   
   token = g_scanner_get_next_token (scanner);
   if (token != G_TOKEN_RIGHT_CURLY)
@@ -1813,6 +2128,28 @@ gtk_rc_parse_style (GScanner *scanner)
   return G_TOKEN_NONE;
 }
 
+const GtkRcProperty*
+_gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
+                                 GQuark      type_name,
+                                 GQuark      property_name)
+{
+  GtkRcProperty *node = NULL;
+
+  g_return_val_if_fail (GTK_IS_RC_STYLE (rc_style), NULL);
+
+  if (rc_style->rc_properties)
+    {
+      GtkRcProperty key;
+
+      key.type_name = type_name;
+      key.property_name = property_name;
+
+      node = g_bsearch_array_lookup (rc_style->rc_properties, &key);
+    }
+
+  return node;
+}
+
 static guint
 gtk_rc_parse_bg (GScanner   *scanner,
                 GtkRcStyle *style)
@@ -2317,7 +2654,7 @@ gtk_rc_parse_color (GScanner *scanner,
 
   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
 
-  /* we don't need to set our own scop here, because
+  /* we don't need to set our own scope here, because
    * we don't need own symbols
    */
   
index 29f8b61a026dfff1ae9d5f6c10ea076b001d6b1f..c68a13d2090439889638a814693e1c8064aa4cce 100644 (file)
@@ -75,6 +75,7 @@ struct _GtkRcStyle
   gint ythickness;
   
   /*< private >*/
+  GBSearchArray *rc_properties;
   
   /* list of RC style lists including this RC style */
   GSList *rc_style_lists;
@@ -91,7 +92,7 @@ struct _GtkRcStyleClass
    * g_object_new (G_OBJECT_TYPE (style), NULL);
    * should work in most cases.
    */
-  GtkRcStyle * (*clone) (GtkRcStyle *rc_style);
+  GtkRcStyle * (*create_rc_style) (GtkRcStyle *rc_style);
 
   /* Fill in engine specific parts of GtkRcStyle by parsing contents
    * of brackets. Returns G_TOKEN_NONE if succesful, otherwise returns
@@ -112,7 +113,7 @@ struct _GtkRcStyleClass
 };
 
 void     gtk_rc_init                   (void);
-void      gtk_rc_add_default_file    (const gchar *filename);
+void      gtk_rc_add_default_file      (const gchar *filename);
 void      gtk_rc_set_default_files      (gchar **filenames);
 gchar**   gtk_rc_get_default_files      (void);
 void     gtk_rc_parse                  (const gchar *filename);
@@ -128,7 +129,7 @@ void          gtk_rc_add_class_style        (GtkRcStyle  *rc_style,
 
 GType       gtk_rc_style_get_type   (void) G_GNUC_CONST;
 GtkRcStyle* gtk_rc_style_new        (void);
-GtkRcStyle *gtk_rc_style_copy       (GtkRcStyle *orig);
+GtkRcStylegtk_rc_style_copy       (GtkRcStyle *orig);
 void        gtk_rc_style_ref        (GtkRcStyle *rc_style);
 void        gtk_rc_style_unref      (GtkRcStyle *rc_style);
 
@@ -194,17 +195,35 @@ typedef enum {
   GTK_RC_TOKEN_LAST
 } GtkRcTokenType;
 
-guint  gtk_rc_parse_color      (GScanner            *scanner,
+GScanner* gtk_rc_scanner_new   (void);
+guint    gtk_rc_parse_color    (GScanner            *scanner,
                                 GdkColor            *color);
-guint  gtk_rc_parse_state      (GScanner            *scanner,
+guint    gtk_rc_parse_state    (GScanner            *scanner,
                                 GtkStateType        *state);
-guint  gtk_rc_parse_priority   (GScanner            *scanner,
+guint    gtk_rc_parse_priority (GScanner            *scanner,
                                 GtkPathPriorityType *priority);
-     
-#ifdef G_OS_WIN32
 
-gchar  *gtk_win32_get_installation_directory (void);
 
+/* rc properties
+ * (structure forward declared in gtkstyle.h)
+ */
+struct _GtkRcProperty
+{
+  /* quark-ified property identifier like "GtkScrollbar::spacing" */
+  GQuark type_name;
+  GQuark property_name;
+
+  /* fields similar to GtkSettingsValue */
+  gchar *origin;
+  GValue value;
+};
+const GtkRcProperty* _gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
+                                                      GQuark      type_name,
+                                                      GQuark      property_name);
+
+
+#ifdef G_OS_WIN32
+gchar*  gtk_win32_get_installation_directory (void);
 #endif
 
 
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
new file mode 100644 (file)
index 0000000..6fa5fea
--- /dev/null
@@ -0,0 +1,682 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include       "gtksettings.h"
+
+
+
+enum {
+  PROP_0,
+  PROP_DOUBLE_CLICK_TIMEOUT,
+  PROP_BELL_PITCH,
+  PROP_BELL_DURATION,
+  PROP_BELL_PERCENT
+};
+
+
+/* --- prototypes --- */
+static void    gtk_settings_init                (GtkSettings           *settings);
+static void    gtk_settings_class_init          (GtkSettingsClass      *class);
+static void    gtk_settings_finalize            (GObject               *object);
+static GObject*        gtk_settings_constructor         (GType                  type,
+                                                 guint                  n_construct_properties,
+                                                 GObjectConstructParam *construct_properties);
+static void    gtk_settings_get_property        (GObject               *object,
+                                                 guint                  property_id,
+                                                 GValue                *value,
+                                                 GParamSpec            *pspec);
+static void    gtk_settings_set_property        (GObject               *object,
+                                                 guint                  property_id,
+                                                 const GValue          *value,
+                                                 GParamSpec            *pspec);
+static void    gtk_settings_notify              (GObject               *object,
+                                                 GParamSpec            *pspec);
+static guint   settings_install_property_parser (GtkSettingsClass      *class,
+                                                 GParamSpec            *pspec,
+                                                 GtkRcPropertyParser    parser);
+
+
+/* --- variables --- */
+static gpointer                 parent_class = NULL;
+static GtkSettings     *the_singleton = NULL;
+static GQuark           quark_property_parser = 0;
+static GQuark           quark_property_id = 0;
+static GSList           *object_list = NULL;
+static guint            class_n_properties = 0;
+
+
+/* --- functions --- */
+GType
+gtk_settings_get_type (void)
+{
+  static GType settings_type = 0;
+  
+  if (!settings_type)
+    {
+      static const GTypeInfo settings_info =
+      {
+       sizeof (GtkSettingsClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_settings_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkSettings),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_settings_init,
+      };
+      
+      settings_type = g_type_register_static (G_TYPE_OBJECT, "GtkSettings", &settings_info, 0);
+    }
+  
+  return settings_type;
+}
+
+static void
+gtk_settings_init (GtkSettings *settings)
+{
+  GObjectClass *gobject_class = G_OBJECT_GET_CLASS (settings);
+  guint i;
+  
+  g_datalist_init (&settings->queued_settings);
+  settings->property_values = NULL;
+  object_list = g_slist_prepend (object_list, settings);
+
+  /* build up property array for all yet existing properties and queue
+   * notification for them (at least notification for internal properties
+   * will instantly be caught)
+   */
+  settings->property_values = g_renew (GValue, settings->property_values, class_n_properties);
+  settings->property_values[class_n_properties - 1].g_type = 0;
+  for (i = 0; i < class_n_properties; i++)
+    {
+      GParamSpec *pspec = gobject_class->property_specs[i]; // FIXME: g_object_list_properties(this_class_type)
+
+      g_value_init (settings->property_values + i, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      g_param_value_set_default (pspec, settings->property_values + i);
+      g_object_notify (G_OBJECT (settings), pspec->name);
+    }
+}
+
+static void
+gtk_settings_class_init (GtkSettingsClass *class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  
+  parent_class = g_type_class_peek_parent (class);
+
+  gobject_class->constructor = gtk_settings_constructor;
+  gobject_class->finalize = gtk_settings_finalize;
+  gobject_class->get_property = gtk_settings_get_property;
+  gobject_class->set_property = gtk_settings_set_property;
+  gobject_class->notify = gtk_settings_notify;
+
+  quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
+  quark_property_id = g_quark_try_string ("GObject-property-id");
+  g_assert (quark_property_id != 0);   /* special quarks from GObjectClass */
+
+  g_assert (PROP_DOUBLE_CLICK_TIMEOUT ==
+           settings_install_property_parser (class,
+                                             g_param_spec_int ("double-click-timeout", "Double Click Timeout", NULL,
+                                                               1, G_MAXINT, 1,
+                                                               G_PARAM_READWRITE),
+                                             NULL));
+  g_assert (PROP_BELL_PITCH ==
+           settings_install_property_parser (class,
+                                             g_param_spec_int ("bell-pitch", "Bell Pitch", NULL,
+                                                               0, G_MAXINT, 440,
+                                                               G_PARAM_READWRITE),
+                                             NULL));
+  g_assert (PROP_BELL_DURATION ==
+           settings_install_property_parser (class,
+                                             g_param_spec_int ("bell_duration", "Bell Duration", NULL,
+                                                               1, G_MAXINT, 250,
+                                                               G_PARAM_READWRITE),
+                                             NULL));
+  g_assert (PROP_BELL_PERCENT ==
+           settings_install_property_parser (class,
+                                             g_param_spec_float ("bell_percent", "Bell Percent", NULL,
+                                                                 0, 100, 80,
+                                                                 G_PARAM_READWRITE),
+                                             NULL));
+}
+
+static void
+gtk_settings_finalize (GObject *object)
+{
+  GtkSettings *settings = GTK_SETTINGS (object);
+  guint i;
+
+  object_list = g_slist_remove (object_list, settings);
+
+  for (i = 0; i < class_n_properties; i++)
+    g_value_unset (settings->property_values + i);
+  g_free (settings->property_values);
+
+  g_datalist_clear (&settings->queued_settings);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GObject*
+gtk_settings_constructor (GType                         type,
+                         guint                  n_construct_properties,
+                         GObjectConstructParam *construct_properties)
+{
+  GObject *object;
+
+  /* currently we're a singleton, that might change with multiple display support though */
+  if (!the_singleton)
+    {
+      object = G_OBJECT_CLASS (parent_class)->constructor (type,
+                                                          n_construct_properties,
+                                                          construct_properties);
+      the_singleton = GTK_SETTINGS (g_object_ref (object));
+    }
+  else
+    object = g_object_ref (G_OBJECT (the_singleton));
+
+  return object;
+}
+
+GtkSettings*
+gtk_settings_get_global (void)
+{
+  if (!the_singleton)
+    g_object_new (GTK_TYPE_SETTINGS, NULL);
+  
+  return the_singleton;        /* we don't add a reference count here, we'd be settings_ref_global() if we did */
+}
+
+static void
+gtk_settings_set_property (GObject      *object,
+                          guint         property_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  GtkSettings *settings = GTK_SETTINGS (object);
+  
+  g_value_copy (value, settings->property_values + property_id - 1);
+}
+
+static void
+gtk_settings_get_property (GObject     *object,
+                          guint        property_id,
+                          GValue      *value,
+                          GParamSpec  *pspec)
+{
+  GtkSettings *settings = GTK_SETTINGS (object);
+  
+  g_value_copy (settings->property_values + property_id - 1, value);
+}
+
+static void
+gtk_settings_notify (GObject    *object,
+                    GParamSpec *pspec)
+{
+  guint property_id = GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_property_id));
+
+#if 1
+  GValue tmp_value = { 0, };
+  gchar *contents;
+  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+  g_object_get_property (object, pspec->name, &tmp_value);
+  contents = g_strdup_value_contents (&tmp_value);
+#endif
+
+  switch (property_id)
+    {
+    case PROP_DOUBLE_CLICK_TIMEOUT:
+      g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+      break;
+    case PROP_BELL_PITCH:
+      g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+      break;
+    case PROP_BELL_DURATION:
+      g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+      break;
+    case PROP_BELL_PERCENT:
+      g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+      break;
+    }
+
+#if 1
+  g_free (contents);
+  g_value_unset (&tmp_value);
+#endif
+}
+
+static void
+apply_queued_setting (GtkSettings      *data,
+                     GParamSpec       *pspec,
+                     GtkSettingsValue *qvalue)
+{
+  gboolean warn_convert = TRUE;
+
+  if (g_value_type_transformable (G_VALUE_TYPE (&qvalue->value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
+    {
+      GValue tmp_value = { 0, };
+
+      warn_convert = FALSE;
+      g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      if (g_param_value_convert (pspec, &qvalue->value, &tmp_value, TRUE))
+       g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+      else
+       {
+         gchar *debug = g_strdup_value_contents (&tmp_value);
+
+         g_message ("%s: rc-value `%s' for rc-property \"%s\" of type `%s' has invalid contents \"%s\"",
+                    qvalue->origin,
+                    G_VALUE_TYPE_NAME (&qvalue->value),
+                    pspec->name,
+                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+                    debug);
+         g_free (debug);
+       }
+      g_value_unset (&tmp_value);
+    }
+  else
+    {
+      GtkRcPropertyParser parser = g_param_spec_get_qdata (pspec, quark_property_parser);
+
+      if (parser)
+       {
+         GValue tmp_value = { 0, };
+
+         g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+         if (parser (pspec, g_value_get_boxed (&qvalue->value), &tmp_value))
+           {
+             warn_convert = FALSE;
+             g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+           }
+         g_value_unset (&tmp_value);
+       }
+    }
+
+  if (warn_convert)
+    g_message ("%s: unable to convert rc-value of type `%s' to rc-property \"%s\" of type `%s'",
+              qvalue->origin,
+              G_VALUE_TYPE_NAME (&qvalue->value),
+              pspec->name,
+              g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
+}
+
+static guint
+settings_install_property_parser (GtkSettingsClass   *class,
+                                 GParamSpec         *pspec,
+                                 GtkRcPropertyParser parser)
+{
+  GSList *node, *next;
+
+  switch (G_TYPE_FUNDAMENTAL (G_PARAM_SPEC_VALUE_TYPE (pspec)))
+    {
+    case G_TYPE_BOOLEAN:
+    case G_TYPE_UCHAR:
+    case G_TYPE_CHAR:
+    case G_TYPE_UINT:
+    case G_TYPE_INT:
+    case G_TYPE_ULONG:
+    case G_TYPE_LONG:
+    case G_TYPE_FLOAT:
+    case G_TYPE_DOUBLE:
+    case G_TYPE_STRING:
+      break;
+    default:
+      if (!parser)
+       g_warning (G_STRLOC ": parser needs to be specified for property \"%s\" of type `%s'",
+                  pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
+      return 0;
+    }
+  if (g_object_class_find_property (G_OBJECT_CLASS (class), pspec->name))
+    {
+      g_warning (G_STRLOC ": an rc-data property \"%s\" already exists",
+                pspec->name);
+      return 0;
+    }
+  
+  for (node = object_list; node; node = node->next)
+    g_object_freeze_notify (node->data);
+
+  g_object_class_install_property (G_OBJECT_CLASS (class), ++class_n_properties, pspec);
+  g_param_spec_set_qdata (pspec, quark_property_parser, parser);
+
+  for (node = object_list; node; node = node->next)
+    {
+      GtkSettings *settings = node->data;
+      GtkSettingsValue *qvalue;
+      
+      settings->property_values = g_renew (GValue, settings->property_values, class_n_properties);
+      settings->property_values[class_n_properties - 1].g_type = 0;
+      g_value_init (settings->property_values + class_n_properties - 1, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      g_param_value_set_default (pspec, settings->property_values + class_n_properties - 1);
+      g_object_notify (G_OBJECT (settings), pspec->name);
+      
+      qvalue = g_datalist_get_data (&settings->queued_settings, pspec->name);
+      if (qvalue)
+       apply_queued_setting (settings, pspec, qvalue);
+    }
+
+  for (node = object_list; node; node = next)
+    {
+      next = node->next;
+      g_object_thaw_notify (node->data);
+    }
+
+  return class_n_properties;
+}
+
+void
+gtk_settings_install_property (GtkSettings *settings,
+                              GParamSpec  *pspec)
+{
+  g_return_if_fail (GTK_IS_SETTINGS (settings));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  
+  settings_install_property_parser (GTK_SETTINGS_GET_CLASS (settings), pspec, NULL);
+}
+
+void
+gtk_settings_install_property_parser (GtkSettings        *settings,
+                                     GParamSpec         *pspec,
+                                     GtkRcPropertyParser parser)
+{
+  g_return_if_fail (GTK_IS_SETTINGS (settings));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (parser != NULL);
+  
+  settings_install_property_parser (GTK_SETTINGS_GET_CLASS (settings), pspec, parser);
+}
+
+static void
+free_value (gpointer data)
+{
+  GtkSettingsValue *qvalue = data;
+  
+  g_value_unset (&qvalue->value);
+  g_free (qvalue->origin);
+  g_free (qvalue);
+}
+
+void
+gtk_settings_set_property_value  (GtkSettings            *settings,
+                                 const gchar            *prop_name,
+                                 const GtkSettingsValue *new_value)
+{
+  GtkSettingsValue *qvalue;
+  GParamSpec *pspec;
+  gchar *name;
+  GQuark name_quark;
+
+  g_return_if_fail (GTK_SETTINGS (settings));
+  g_return_if_fail (prop_name != NULL);
+  g_return_if_fail (new_value != NULL);
+  g_return_if_fail (new_value->origin != NULL);
+
+  if (!G_VALUE_HOLDS_LONG (&new_value->value) &&
+      !G_VALUE_HOLDS_DOUBLE (&new_value->value) &&
+      !G_VALUE_HOLDS_STRING (&new_value->value) &&
+      !G_VALUE_HOLDS (&new_value->value, G_TYPE_GSTRING))
+    {
+      g_warning (G_STRLOC ": value type invalid");
+      return;
+    }
+  
+  name = g_strdup (prop_name);
+  g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+  name_quark = g_quark_try_string (name);
+  if (name_quark)
+    g_free (name);
+  else
+    name_quark = g_quark_from_string (name);
+
+  qvalue = g_datalist_id_get_data (&settings->queued_settings, name_quark);
+  if (!qvalue)
+    {
+      qvalue = g_new0 (GtkSettingsValue, 1);
+      g_datalist_id_set_data_full (&settings->queued_settings, name_quark, qvalue, free_value);
+    }
+  else
+    {
+      g_free (qvalue->origin);
+      g_value_unset (&qvalue->value);
+    }
+  qvalue->origin = g_strdup (new_value->origin);
+  g_value_init (&qvalue->value, G_VALUE_TYPE (&new_value->value));
+  g_value_copy (&new_value->value, &qvalue->value);
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), g_quark_to_string (name_quark));
+  if (pspec)
+    apply_queued_setting (settings, pspec, qvalue);
+}
+
+void
+gtk_settings_set_string_property (GtkSettings *settings,
+                                 const gchar *name,
+                                 const gchar *v_string,
+                                 const gchar *origin)
+{
+  GtkSettingsValue svalue = { NULL, { 0, }, };
+
+  g_return_if_fail (GTK_SETTINGS (settings));
+  g_return_if_fail (name != NULL);
+  g_return_if_fail (v_string != NULL);
+  g_return_if_fail (origin != NULL);
+
+  svalue.origin = (gchar*) origin;
+  g_value_init (&svalue.value, G_TYPE_STRING);
+  g_value_set_static_string (&svalue.value, v_string);
+  gtk_settings_set_property_value (settings, name, &svalue);
+  g_value_unset (&svalue.value);
+}
+
+void
+gtk_settings_set_long_property (GtkSettings *settings,
+                               const gchar *name,
+                               glong        v_long,
+                               const gchar *origin)
+{
+  GtkSettingsValue svalue = { NULL, { 0, }, };
+  
+  g_return_if_fail (GTK_SETTINGS (settings));
+  g_return_if_fail (name != NULL);
+  g_return_if_fail (origin != NULL);
+
+  svalue.origin = (gchar*) origin;
+  g_value_init (&svalue.value, G_TYPE_LONG);
+  g_value_set_long (&svalue.value, v_long);
+  gtk_settings_set_property_value (settings, name, &svalue);
+  g_value_unset (&svalue.value);
+}
+
+void
+gtk_settings_set_double_property (GtkSettings *settings,
+                                 const gchar *name,
+                                 gdouble      v_double,
+                                 const gchar *origin)
+{
+  GtkSettingsValue svalue = { NULL, { 0, }, };
+
+  g_return_if_fail (GTK_SETTINGS (settings));
+  g_return_if_fail (name != NULL);
+  g_return_if_fail (origin != NULL);
+
+  svalue.origin = (gchar*) origin;
+  g_value_init (&svalue.value, G_TYPE_DOUBLE);
+  g_value_set_double (&svalue.value, v_double);
+  gtk_settings_set_property_value (settings, name, &svalue);
+  g_value_unset (&svalue.value);
+}
+
+gboolean
+gtk_rc_property_parse_color (const GParamSpec *pspec,
+                            const GString    *gstring,
+                            GValue           *property_value)
+{
+  GdkColor color = { 0, 0, 0, 0, };
+  GScanner *scanner;
+  gboolean success;
+
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+  g_return_val_if_fail (G_VALUE_HOLDS (property_value, GTK_TYPE_GDK_COLOR), FALSE);
+
+  scanner = gtk_rc_scanner_new ();
+  g_scanner_input_text (scanner, gstring->str, gstring->len);
+  if (gtk_rc_parse_color (scanner, &color) == G_TOKEN_NONE &&
+      g_scanner_get_next_token (scanner) == G_TOKEN_EOF)
+    {
+      g_value_set_boxed (property_value, &color);
+      success = TRUE;
+    }
+  else
+    success = FALSE;
+  g_scanner_destroy (scanner);
+
+  return success;
+}
+
+gboolean
+gtk_rc_property_parse_enum (const GParamSpec *pspec,
+                           const GString    *gstring,
+                           GValue           *property_value)
+{
+  gboolean need_closing_brace = FALSE, success = FALSE;
+  GScanner *scanner;
+  GEnumValue *enum_value = NULL;
+
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+  g_return_val_if_fail (G_VALUE_HOLDS_ENUM (property_value), FALSE);
+
+  scanner = gtk_rc_scanner_new ();
+  g_scanner_input_text (scanner, gstring->str, gstring->len);
+
+  /* we just want to parse _one_ value, but for consistency with flags parsing
+   * we support optional paranthesis
+   */
+  g_scanner_get_next_token (scanner);
+  if (scanner->token == '(')
+    {
+      need_closing_brace = TRUE;
+      g_scanner_get_next_token (scanner);
+    }
+  if (scanner->token == G_TOKEN_IDENTIFIER)
+    {
+      GEnumClass *class = G_PARAM_SPEC_ENUM (pspec)->enum_class;
+
+      enum_value = g_enum_get_value_by_name (class, scanner->value.v_identifier);
+      if (!enum_value)
+       enum_value = g_enum_get_value_by_nick (class, scanner->value.v_identifier);
+      if (enum_value)
+       {
+         g_value_set_enum (property_value, enum_value->value);
+         success = TRUE;
+       }
+    }
+  else if (scanner->token == G_TOKEN_INT)
+    {
+      g_value_set_enum (property_value, scanner->value.v_int);
+      success = TRUE;
+    }
+  if (need_closing_brace && g_scanner_get_next_token (scanner) != ')')
+    success = FALSE;
+  if (g_scanner_get_next_token (scanner) != G_TOKEN_EOF)
+    success = FALSE;
+
+  g_scanner_destroy (scanner);
+
+  return success;
+}
+
+static guint
+parse_flags_value (GScanner    *scanner,
+                  GFlagsClass *class,
+                  guint       *number)
+{
+  g_scanner_get_next_token (scanner);
+  if (scanner->token == G_TOKEN_IDENTIFIER)
+    {
+      GFlagsValue *flags_value;
+
+      flags_value = g_flags_get_value_by_name (class, scanner->value.v_identifier);
+      if (!flags_value)
+       flags_value = g_flags_get_value_by_nick (class, scanner->value.v_identifier);
+      if (flags_value)
+       {
+         *number |= flags_value->value;
+         return G_TOKEN_NONE;
+       }
+    }
+  else if (scanner->token == G_TOKEN_INT)
+    {
+      *number |= scanner->value.v_int;
+      return G_TOKEN_NONE;
+    }
+  return G_TOKEN_IDENTIFIER;
+}
+
+gboolean
+gtk_rc_property_parse_flags (const GParamSpec *pspec,
+                            const GString    *gstring,
+                            GValue           *property_value)
+{
+  GFlagsClass *class;
+  gboolean success = FALSE;
+  GScanner *scanner;
+
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+  g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (property_value), FALSE);
+
+  class = G_PARAM_SPEC_FLAGS (pspec)->flags_class;
+  scanner = gtk_rc_scanner_new ();
+  g_scanner_input_text (scanner, gstring->str, gstring->len);
+
+  /* parse either a single flags value or a "\( ... [ \| ... ] \)" compound */
+  if (g_scanner_peek_next_token (scanner) == G_TOKEN_IDENTIFIER ||
+      scanner->next_token == G_TOKEN_INT)
+    {
+      guint token, flags_value = 0;
+      
+      token = parse_flags_value (scanner, class, &flags_value);
+
+      if (token == G_TOKEN_NONE && g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
+       {
+         success = TRUE;
+         g_value_set_flags (property_value, flags_value);
+       }
+      
+    }
+  else if (g_scanner_get_next_token (scanner) == '(')
+    {
+      guint token, flags_value = 0;
+
+      /* parse first value */
+      token = parse_flags_value (scanner, class, &flags_value);
+
+      /* parse nth values, preceeded by '|' */
+      while (token == G_TOKEN_NONE && g_scanner_get_next_token (scanner) == '|')
+       token = parse_flags_value (scanner, class, &flags_value);
+
+      /* done, last token must have closed expression */
+      if (token == G_TOKEN_NONE && scanner->token == ')' &&
+         g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
+       {
+         g_value_set_flags (property_value, flags_value);
+         success = TRUE;
+       }
+    }
+  g_scanner_destroy (scanner);
+
+  return success;
+}
diff --git a/gtk/gtksettings.h b/gtk/gtksettings.h
new file mode 100644 (file)
index 0000000..43cd683
--- /dev/null
@@ -0,0 +1,111 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SETTINGS_H__
+#define __GTK_SETTINGS_H__
+
+#include       <gtk/gtkrc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* -- type macros --- */
+#define GTK_TYPE_SETTINGS            (gtk_settings_get_type ())
+#define GTK_SETTINGS(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_SETTINGS, GtkSettings))
+#define GTK_SETTINGS_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_SETTINGS, GtkSettingsClass))
+#define GTK_IS_SETTINGS(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_SETTINGS))
+#define GTK_IS_SETTINGS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SETTINGS))
+#define GTK_SETTINGS_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_SETTINGS, GtkSettingsClass))
+
+
+/* --- typedefs --- */
+typedef struct    _GtkSettings      GtkSettings;
+typedef struct    _GtkSettingsClass GtkSettingsClass;
+typedef struct    _GtkSettingsValue GtkSettingsValue;
+
+
+/* --- structures --- */
+struct _GtkSettings
+{
+  GObject parent_instance;
+
+  GData  *queued_settings;     /* of type GtkSettingsValue* */
+  GValue *property_values;
+};
+struct _GtkSettingsClass
+{
+  GObjectClass parent_class;
+  
+};
+struct _GtkSettingsValue
+{
+  /* origin should be something like "filename:linenumber" for rc files,
+   * or e.g. "XProperty" for other sources
+   */
+  gchar *origin;
+
+  /* valid types are LONG, DOUBLE and STRING corresponding to the token parsed,
+   * or a GSTRING holding an unparsed statement
+   */
+  GValue value;
+};
+
+
+/* --- functions --- */
+GType          gtk_settings_get_type                (void);
+GtkSettings*   gtk_settings_get_global              (void);    /* singleton */
+void           gtk_settings_install_property        (GtkSettings        *settings,
+                                                     GParamSpec         *pspec);
+void           gtk_settings_install_property_parser (GtkSettings        *settings,
+                                                     GParamSpec         *pspec,
+                                                     GtkRcPropertyParser parser);
+
+/* --- precoded parsing functions --- */
+gboolean       gtk_rc_property_parse_color (const GParamSpec *pspec,
+                                            const GString    *gstring,
+                                            GValue           *property_value);
+gboolean       gtk_rc_property_parse_enum  (const GParamSpec *pspec,
+                                            const GString    *gstring,
+                                            GValue           *property_value);
+gboolean       gtk_rc_property_parse_flags (const GParamSpec *pspec,
+                                            const GString    *gstring,
+                                            GValue           *property_value);
+
+/*< private >*/
+void           gtk_settings_set_property_value  (GtkSettings   *settings,
+                                                 const gchar   *name,
+                                                 const GtkSettingsValue *svalue);
+void           gtk_settings_set_string_property (GtkSettings   *settings,
+                                                 const gchar   *name,
+                                                 const gchar   *v_string,
+                                                 const gchar   *origin);
+void           gtk_settings_set_long_property   (GtkSettings   *settings,
+                                                 const gchar   *name,
+                                                 glong          v_long,
+                                                 const gchar   *origin);
+void           gtk_settings_set_double_property (GtkSettings   *settings,
+                                                 const gchar   *name,
+                                                 gdouble        v_double,
+                                                 const gchar   *origin);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTK_SETTINGS_H__ */
index f33a3d59e24d9c7d4558bebc95a2f5cf31cb0071..cc6a0acab6771ef0824e4a8391fbc066932c8139 100644 (file)
@@ -36,6 +36,7 @@
 #include "gtkspinbutton.h"
 #include "gtkmain.h"
 #include "gtksignal.h"
+#include "gtksettings.h"
 
 
 #define MIN_SPIN_BUTTON_WIDTH              30
@@ -55,7 +56,6 @@ enum {
   ARG_NUMERIC,
   ARG_WRAP,
   ARG_UPDATE_POLICY,
-  ARG_SHADOW_TYPE,
   ARG_VALUE
 };
 
@@ -121,6 +121,7 @@ static void gtk_spin_button_real_spin      (GtkSpinButton      *spin_button,
 static gint gtk_spin_button_default_input  (GtkSpinButton      *spin_button,
                                            gfloat             *new_val);
 static gint gtk_spin_button_default_output (GtkSpinButton      *spin_button);
+static gint spin_button_get_shadow_type    (GtkSpinButton      *spin_button);
 
 
 static GtkEntryClass *parent_class = NULL;
@@ -221,15 +222,17 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
                           GTK_TYPE_SPIN_BUTTON_UPDATE_POLICY,
                           GTK_ARG_READWRITE,
                           ARG_UPDATE_POLICY);
-  gtk_object_add_arg_type ("GtkSpinButton::shadow_type",
-                          GTK_TYPE_SHADOW_TYPE,
-                          GTK_ARG_READWRITE,
-                          ARG_SHADOW_TYPE);
   gtk_object_add_arg_type ("GtkSpinButton::value",
                           GTK_TYPE_FLOAT,
                           GTK_ARG_READWRITE,
                           ARG_VALUE);
-
+  
+  gtk_widget_class_install_style_property_parser (widget_class,
+                                                 g_param_spec_enum ("shadow_type", "Shadow Type", NULL,
+                                                                    GTK_TYPE_SHADOW_TYPE,
+                                                                    GTK_SHADOW_NONE,
+                                                                    G_PARAM_READABLE),
+                                                 gtk_rc_property_parse_enum);
   spinbutton_signals[INPUT] =
     gtk_signal_new ("input",
                    GTK_RUN_LAST,
@@ -290,9 +293,6 @@ gtk_spin_button_set_arg (GtkObject        *object,
     case ARG_UPDATE_POLICY:
       gtk_spin_button_set_update_policy (spin_button, GTK_VALUE_ENUM (*arg));
       break;
-    case ARG_SHADOW_TYPE:
-      gtk_spin_button_set_shadow_type (spin_button, GTK_VALUE_ENUM (*arg));
-      break;
     case ARG_VALUE:
       gtk_spin_button_set_value (spin_button, GTK_VALUE_FLOAT (*arg));
       break;
@@ -333,9 +333,6 @@ gtk_spin_button_get_arg (GtkObject        *object,
     case ARG_UPDATE_POLICY:
       GTK_VALUE_ENUM (*arg) = spin_button->update_policy;
       break;
-    case ARG_SHADOW_TYPE:
-      GTK_VALUE_ENUM (*arg) = spin_button->shadow_type;
-      break;
     case ARG_VALUE:
       GTK_VALUE_FLOAT (*arg) = spin_button->adjustment->value;
       break;
@@ -350,7 +347,6 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
 {
   spin_button->adjustment = NULL;
   spin_button->panel = NULL;
-  spin_button->shadow_type = GTK_SHADOW_NONE;
   spin_button->timer = 0;
   spin_button->ev_time = 0;
   spin_button->climb_rate = 0.0;
@@ -584,14 +580,17 @@ gtk_spin_button_expose (GtkWidget      *widget,
 
   if (GTK_WIDGET_DRAWABLE (widget))
     {
+      GtkShadowType shadow_type;
+
       /* FIXME this seems like really broken code -
        * why aren't we looking at event->window
        * and acting accordingly?
        */
-      
-      if (spin->shadow_type != GTK_SHADOW_NONE)
+
+      shadow_type = spin_button_get_shadow_type (spin);
+      if (shadow_type != GTK_SHADOW_NONE)
        gtk_paint_box (widget->style, spin->panel,
-                      GTK_STATE_NORMAL, spin->shadow_type,
+                      GTK_STATE_NORMAL, shadow_type,
                       &event->area, widget, "spinbutton",
                       0, 0, 
                       ARROW_SIZE + 2 * widget->style->xthickness,
@@ -616,6 +615,7 @@ static void
 gtk_spin_button_draw_arrow (GtkSpinButton *spin_button, 
                            guint          arrow)
 {
+  GtkShadowType spin_shadow_type;
   GtkStateType state_type;
   GtkShadowType shadow_type;
   GtkWidget *widget;
@@ -626,6 +626,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
   g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
   
   widget = GTK_WIDGET (spin_button);
+  spin_shadow_type = spin_button_get_shadow_type (spin_button);
 
   if (GTK_WIDGET_DRAWABLE (spin_button))
     {
@@ -659,7 +660,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
        }
       if (arrow == GTK_ARROW_UP)
        {
-         if (spin_button->shadow_type != GTK_SHADOW_NONE)
+         if (spin_shadow_type != GTK_SHADOW_NONE)
            {
              x = widget->style->xthickness;
              y = widget->style->ythickness;
@@ -678,7 +679,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
        }
       else
        {
-         if (spin_button->shadow_type != GTK_SHADOW_NONE)
+         if (spin_shadow_type != GTK_SHADOW_NONE)
            {
              x = widget->style->xthickness;
              y = widget->requisition.height / 2;
@@ -1563,19 +1564,14 @@ gtk_spin_button_set_wrap (GtkSpinButton  *spin_button,
   spin_button->wrap = (wrap != 0);
 }
 
-void
-gtk_spin_button_set_shadow_type (GtkSpinButton *spin_button,
-                                GtkShadowType  shadow_type)
+static gint
+spin_button_get_shadow_type (GtkSpinButton *spin_button)
 {
-  g_return_if_fail (spin_button != NULL);
-  g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
+  GtkShadowType rc_shadow_type;
 
-  if (shadow_type != spin_button->shadow_type)
-    {
-      spin_button->shadow_type = shadow_type;
-      if (GTK_WIDGET_DRAWABLE (spin_button))
-       gtk_widget_queue_draw (GTK_WIDGET (spin_button));
-    }
+  gtk_widget_style_get (GTK_WIDGET (spin_button), "shadow_type", &rc_shadow_type, NULL);
+
+  return rc_shadow_type;
 }
 
 void
index 2f46ebdcb4aa2ba59ea1b01df141c0a48cfc7090..04a4c7906d35473859d92a89b8da74a5619cc8b6 100644 (file)
@@ -79,7 +79,6 @@ struct _GtkSpinButton
   GtkAdjustment *adjustment;
   
   GdkWindow *panel;
-  GtkShadowType shadow_type;
   
   guint32 timer;
   guint32 ev_time;
@@ -149,9 +148,6 @@ void                gtk_spin_button_spin               (GtkSpinButton  *spin_button,
 void           gtk_spin_button_set_wrap           (GtkSpinButton  *spin_button,
                                                    gboolean        wrap);
 
-void           gtk_spin_button_set_shadow_type    (GtkSpinButton  *spin_button,
-                                                   GtkShadowType   shadow_type);
-
 void           gtk_spin_button_set_snap_to_ticks  (GtkSpinButton  *spin_button,
                                                    gboolean        snap_to_ticks);
 void            gtk_spin_button_update             (GtkSpinButton  *spin_button);
index 4f4922d7b9a2830cbb0c6f09ed97ad472a1f71ce..ebd5d0de61123744f0820786f5e61dca0035cbfb 100644 (file)
 #define LIGHTNESS_MULT  1.3
 #define DARKNESS_MULT   0.7
 
-/* actually glib should do that for us */
-#ifndef M_PI
-#define M_PI    3.14159265358979323846
-#endif /* M_PI */
-#ifndef M_PI_4
-#define M_PI_4  0.78539816339744830962
-#endif /* M_PI_4 */
-
-static void         gtk_style_realize (GtkStyle    *style,
-                                       GdkColormap *colormap);
-
-static void      gtk_style_real_realize        (GtkStyle     *style);
-static void      gtk_style_real_unrealize      (GtkStyle     *style);
-static void      gtk_style_real_copy           (GtkStyle     *style,
-                                               GtkStyle     *src);
-static void      gtk_style_real_set_background (GtkStyle     *style,
-                                               GdkWindow    *window,
-                                               GtkStateType  state_type);
-static GtkStyle *gtk_style_real_clone          (GtkStyle     *style);
-static void      gtk_style_real_init_from_rc   (GtkStyle     *style,
-                                                GtkRcStyle   *rc_style);
-
 
+/* --- typedefs & structures --- */
+typedef struct {
+  GType       widget_type;
+  GParamSpec *pspec;
+  GValue      value;
+} PropertyValue;
+
+
+/* --- prototypes --- */
+static void     gtk_style_init                 (GtkStyle       *style);
+static void     gtk_style_class_init           (GtkStyleClass  *klass);
+static void     gtk_style_finalize             (GObject        *object);
+static void     gtk_style_realize              (GtkStyle       *style,
+                                                GdkColormap    *colormap);
+static void      gtk_style_real_realize        (GtkStyle       *style);
+static void      gtk_style_real_unrealize      (GtkStyle       *style);
+static void      gtk_style_real_copy           (GtkStyle       *style,
+                                               GtkStyle        *src);
+static void      gtk_style_real_set_background (GtkStyle       *style,
+                                               GdkWindow       *window,
+                                               GtkStateType     state_type);
+static GtkStyle *gtk_style_real_clone          (GtkStyle       *style);
+static void      gtk_style_real_init_from_rc   (GtkStyle       *style,
+                                                GtkRcStyle     *rc_style);
 static GdkPixbuf *gtk_default_render_icon      (GtkStyle            *style,
                                                 const GtkIconSource *source,
                                                 GtkTextDirection     direction,
@@ -66,7 +68,6 @@ static GdkPixbuf *gtk_default_render_icon      (GtkStyle            *style,
                                                 GtkIconSize          size,
                                                 GtkWidget           *widget,
                                                 const gchar         *detail);
-
 static void gtk_default_draw_hline      (GtkStyle        *style,
                                         GdkWindow       *window,
                                         GtkStateType     state_type,
@@ -285,13 +286,18 @@ static void gtk_default_draw_layout     (GtkStyle        *style,
                                          gint             x,
                                          gint             y,
                                          PangoLayout     *layout);
-
-static void gtk_style_shade (GdkColor *a, GdkColor *b, gdouble k);
-static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b);
-static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s);
-
-GdkFont *default_font = NULL;
-
+static void gtk_style_shade            (GdkColor        *a,
+                                        GdkColor        *b,
+                                        gdouble          k);
+static void rgb_to_hls                 (gdouble         *r,
+                                        gdouble         *g,
+                                        gdouble         *b);
+static void hls_to_rgb                 (gdouble         *h,
+                                        gdouble         *l,
+                                        gdouble         *s);
+
+
+/* --- variables --- */
 static GdkColor gtk_default_normal_fg =      { 0,      0,      0,      0 };
 static GdkColor gtk_default_active_fg =      { 0,      0,      0,      0 };
 static GdkColor gtk_default_prelight_fg =    { 0,      0,      0,      0 };
@@ -305,19 +311,18 @@ static GdkColor gtk_default_selected_bg =    { 0,      0,      0, 0x9c40 };
 static GdkColor gtk_default_insensitive_bg = { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
 
 static gpointer parent_class = NULL;
+static GdkFont *static_default_font = NULL;
 
-static void gtk_style_init       (GtkStyle      *style);
-static void gtk_style_class_init (GtkStyleClass *klass);
-static void gtk_style_finalize   (GObject       *object);
 
+/* --- functions --- */
 GType
 gtk_style_get_type (void)
 {
-  static GType object_type = 0;
-
-  if (!object_type)
+  static GType style_type = 0;
+  
+  if (!style_type)
     {
-      static const GTypeInfo object_info =
+      static const GTypeInfo style_info =
       {
         sizeof (GtkStyleClass),
         (GBaseInitFunc) NULL,
@@ -330,12 +335,12 @@ gtk_style_get_type (void)
         (GInstanceInitFunc) gtk_style_init,
       };
       
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "GtkStyle",
-                                            &object_info, 0);
+      style_type = g_type_register_static (G_TYPE_OBJECT,
+                                          "GtkStyle",
+                                          &style_info, 0);
     }
   
-  return object_type;
+  return style_type;
 }
 
 static void
@@ -345,18 +350,18 @@ gtk_style_init (GtkStyle *style)
   
   style->font_desc = pango_font_description_from_string ("Sans 10");
 
-  if (!default_font)
+  if (!static_default_font)
     {
-      default_font = gdk_font_from_description (style->font_desc);
+      static_default_font = gdk_font_from_description (style->font_desc);
 
-      if (!default_font) 
-       default_font = gdk_font_load ("fixed");
+      if (!static_default_font) 
+       static_default_font = gdk_font_load ("fixed");
 
-      if (!default_font) 
-       g_error ("Unable to load \"fixed\" font!");
+      if (!static_default_font) 
+       g_error ("Unable to load \"fixed\" font");
     }
   
-  style->font = default_font;
+  style->font = static_default_font;
   gdk_font_ref (style->font);
 
   style->attach_count = 0;
@@ -413,6 +418,8 @@ gtk_style_init (GtkStyle *style)
 
   style->xthickness = 2;
   style->ythickness = 2;
+
+  style->property_cache = NULL;
 }
 
 static void
@@ -460,6 +467,21 @@ gtk_style_finalize (GObject *object)
   GtkStyle *style = GTK_STYLE (object);
 
   g_return_if_fail (style->attach_count == 0);
+
+  if (style->property_cache)
+    {
+      guint i;
+
+      for (i = 0; i < style->property_cache->n_nodes; i++)
+       {
+         PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+         g_param_spec_unref (node->pspec);
+         g_value_unset (&node->value);
+       }
+      g_bsearch_array_destroy (style->property_cache);
+      style->property_cache = NULL;
+    }
   
   if (style->styles)
     {
@@ -471,7 +493,7 @@ gtk_style_finalize (GObject *object)
          
           while (tmp_list)
             {
-              ((GtkStyle*) tmp_list->data)->styles = style->styles->next;
+              GTK_STYLE (tmp_list->data)->styles = style->styles->next;
               tmp_list = tmp_list->next;
             }
           g_slist_free_1 (style->styles);
@@ -668,10 +690,8 @@ gtk_style_lookup_icon_set (GtkStyle   *style,
   iter = style->icon_factories;
   while (iter != NULL)
     {
-      GtkIconSet *icon_set =
-        gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
-                                 stock_id);
-
+      GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
+                                                     stock_id);
       if (icon_set)
         return icon_set;
       
@@ -1062,6 +1082,22 @@ gtk_style_real_copy (GtkStyle *style,
   style->rc_style = src->rc_style;
   if (src->rc_style)
     gtk_rc_style_ref (src->rc_style);
+
+  /* don't copy, just clear cache */
+  if (style->property_cache)
+    {
+      guint i;
+
+      for (i = 0; i < style->property_cache->n_nodes; i++)
+       {
+         PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+         g_param_spec_unref (node->pspec);
+         g_value_unset (&node->value);
+       }
+      g_bsearch_array_destroy (style->property_cache);
+      style->property_cache = NULL;
+    }
 }
 
 static void
@@ -1071,6 +1107,22 @@ gtk_style_real_init_from_rc (GtkStyle   *style,
   GdkFont *old_font;
   gint i;
 
+  /* cache _should_ be still empty */
+  if (style->property_cache)
+    {
+      guint i;
+
+      for (i = 0; i < style->property_cache->n_nodes; i++)
+       {
+         PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+         g_param_spec_unref (node->pspec);
+         g_value_unset (&node->value);
+       }
+      g_bsearch_array_destroy (style->property_cache);
+      style->property_cache = NULL;
+    }
+
   if (rc_style->font_desc)
     {
       pango_font_description_free (style->font_desc);
@@ -1101,7 +1153,6 @@ gtk_style_real_init_from_rc (GtkStyle   *style,
   if (rc_style->ythickness >= 0)
     style->ythickness = rc_style->ythickness;
 
-  
   if (rc_style->icon_factories)
     {
       GSList *iter;
@@ -1118,6 +1169,118 @@ gtk_style_real_init_from_rc (GtkStyle   *style,
     }
 }
 
+static gint
+style_property_values_cmp (gconstpointer bsearch_node1,
+                          gconstpointer bsearch_node2)
+{
+  const PropertyValue *val1 = bsearch_node1;
+  const PropertyValue *val2 = bsearch_node2;
+  gint cmp;
+
+  cmp = G_BSEARCH_ARRAY_CMP (val1->widget_type, val2->widget_type);
+  if (cmp == 0)
+    cmp = G_BSEARCH_ARRAY_CMP (val1->pspec, val2->pspec);
+
+  return cmp;
+}
+
+const GValue*
+_gtk_style_peek_property_value (GtkStyle           *style,
+                               GType               widget_type,
+                               GParamSpec         *pspec,
+                               GtkRcPropertyParser parser)
+{
+  PropertyValue *pcache, key = { 0, NULL, { 0, } };
+  const GtkRcProperty *rcprop = NULL;
+
+  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
+  g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
+  g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
+
+  /* need value cache array */
+  if (!style->property_cache)
+    style->property_cache = g_bsearch_array_new (sizeof (PropertyValue),
+                                                style_property_values_cmp,
+                                                0);
+  /* lookup, or insert value if not yet present */
+  key.widget_type = widget_type;
+  key.pspec = pspec;
+  pcache = g_bsearch_array_insert (style->property_cache, &key, FALSE);
+  if (G_VALUE_TYPE (&pcache->value))
+    return &pcache->value;
+
+  /* cache miss, initialize value type, then set contents */
+  g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+
+  /* value provided by rc style? */
+  if (style->rc_style)
+    {
+      GQuark prop_quark = g_quark_from_string (pspec->name);
+
+      do
+       {
+         rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
+                                                    g_type_qname (widget_type),
+                                                    prop_quark);
+         if (rcprop)
+           break;
+         widget_type = g_type_parent (widget_type);
+       }
+      while (g_type_is_a (widget_type, pspec->owner_type));
+    }
+
+  /* when supplied by rc style, we need to convert */
+  if (rcprop)
+    {
+      if (G_VALUE_TYPE (&rcprop->value) == G_TYPE_GSTRING)
+       {
+         GString *gstring;
+         
+         /* value still unparsed, need to revert to user supplied parser function */
+         
+         gstring = g_value_get_boxed (&rcprop->value);
+         
+         if (!parser || !parser (pspec, gstring, &pcache->value) ||
+             g_param_value_validate (pspec, &pcache->value))
+           {
+             gchar *contents = g_strescape (gstring->str, NULL);
+
+             g_message ("%s: failed to parse property `%s::%s' of type `%s' from rc file value \"%s\"",
+                        rcprop->origin,
+                        g_type_name (pspec->owner_type), pspec->name,
+                        g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+                        gstring->str);
+             g_free (contents);
+             rcprop = NULL;
+           }
+       }
+      else
+       {
+         /* we use the normal conversion functionality of param specs */
+         if (!g_param_value_convert (pspec, &rcprop->value, &pcache->value, TRUE))
+           {
+             gchar *contents = g_strdup_value_contents (&rcprop->value);
+             
+             g_message ("%s: failed to retrive property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
+                        rcprop->origin,
+                        g_type_name (pspec->owner_type), pspec->name,
+                        g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+                        contents,
+                        G_VALUE_TYPE_NAME (&rcprop->value));
+             g_free (contents);
+             rcprop = NULL;
+           }
+       }
+    }
+  
+  /* not supplied by rc style (or conversion failed), revert to default */
+  if (!rcprop)
+    g_param_value_set_default (pspec, &pcache->value);
+
+  return &pcache->value;
+}
+
 static void
 gtk_style_real_realize (GtkStyle *style)
 {
@@ -1146,7 +1309,7 @@ gtk_style_real_realize (GtkStyle *style)
     }
   else if (style->font->type == GDK_FONT_FONTSET)
     {
-      gc_values.font = default_font;
+      gc_values.font = static_default_font;
     }
   
   gc_values.foreground = style->black;
@@ -1394,7 +1557,7 @@ gtk_default_render_icon (GtkStyle            *style,
   
   if (!gtk_icon_size_lookup (size, &width, &height))
     {
-      g_warning ("Bad icon size '%s' passed to render_icon", size);
+      g_warning (G_STRLOC ": invalid icon size `%d'", size);
       return NULL;
     }
 
@@ -1728,8 +1891,8 @@ gtk_default_draw_polygon (GtkStyle      *style,
                           gint           npoints,
                           gboolean       fill)
 {
-  static const gdouble pi_over_4 = M_PI_4;
-  static const gdouble pi_3_over_4 = M_PI_4 * 3;
+  static const gdouble pi_over_4 = G_PI_4;
+  static const gdouble pi_3_over_4 = G_PI_4 * 3;
   GdkGC *gc1;
   GdkGC *gc2;
   GdkGC *gc3;
index bcb02be50578b0d69c80d7f1ea05ae37485f1015..407f9ae77c4cbf8b0da8e7e5349b870759d9a9d3 100644 (file)
@@ -36,9 +36,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-typedef struct _GtkStyle       GtkStyle;
-typedef struct _GtkStyleClass  GtkStyleClass;
-
 #define GTK_TYPE_STYLE              (gtk_style_get_type ())
 #define GTK_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_STYLE, GtkStyle))
 #define GTK_STYLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STYLE, GtkStyleClass))
@@ -49,10 +46,16 @@ typedef struct _GtkStyleClass  GtkStyleClass;
 /* Some forward declarations needed to rationalize the header
  * files.
  */
+typedef struct _GtkStyle       GtkStyle;
+typedef struct _GtkStyleClass  GtkStyleClass;
 typedef struct _GtkThemeEngine GtkThemeEngine;
 typedef struct _GtkRcStyle     GtkRcStyle;
 typedef struct _GtkIconSet     GtkIconSet;
 typedef struct _GtkIconSource  GtkIconSource;
+typedef struct _GtkRcProperty  GtkRcProperty;
+typedef gboolean (*GtkRcPropertyParser) (const GParamSpec *pspec,
+                                        const GString    *rc_string,
+                                        GValue           *property_value);
 
 /* We make this forward declaration here, since we pass
  * GtkWidgt's to the draw functions.
@@ -64,7 +67,7 @@ typedef struct _GtkWidget      GtkWidget;
  */
 #define GTK_STYLE_NUM_STYLECOLORS()    (7 * 5)
 
-#define GTK_STYLE_ATTACHED(style)      (((GtkStyle*) (style))->attach_count > 0)
+#define GTK_STYLE_ATTACHED(style)      (GTK_STYLE (style)->attach_count > 0)
 
 struct _GtkStyle
 {
@@ -107,12 +110,12 @@ struct _GtkStyle
   gint depth;
   GdkColormap *colormap;
   
-  GtkRcStyle    *rc_style;     /* the Rc style from which this style
-                                * was created
-                                */
-  GSList        *styles;
+  /* the RcStyle from which this style was created */
+  GtkRcStyle    *rc_style;
 
-  GSList         *icon_factories;
+  GSList        *styles;         /* of type GtkStyle* */
+  GBSearchArray         *property_cache;
+  GSList         *icon_factories; /* of type GtkIconFactory* */
 };
 
 struct _GtkStyleClass
@@ -409,7 +412,7 @@ void          gtk_style_apply_default_background (GtkStyle     *style,
 
 GtkIconSet* gtk_style_lookup_icon_set (GtkStyle            *style,
                                        const gchar         *stock_id);
-GdkPixbuf * gtk_style_render_icon     (GtkStyle            *style,
+GdkPixbuf gtk_style_render_icon     (GtkStyle            *style,
                                        const GtkIconSource *source,
                                        GtkTextDirection     direction,
                                        GtkStateType         state,
@@ -461,14 +464,6 @@ void gtk_draw_diamond    (GtkStyle        *style,
                          gint             y,
                          gint             width,
                          gint             height);
-#ifndef GTK_DISABLE_DEPRECATED
-void gtk_draw_string     (GtkStyle        *style,
-                         GdkWindow       *window,
-                         GtkStateType     state_type,
-                         gint             x,
-                         gint             y,
-                         const gchar     *string);
-#endif /* GTK_DISABLE_DEPRECATED */
 void gtk_draw_box        (GtkStyle        *style,
                          GdkWindow       *window,
                          GtkStateType     state_type,
@@ -640,17 +635,6 @@ void gtk_paint_diamond    (GtkStyle        *style,
                           gint             y,
                           gint             width,
                           gint             height);
-#ifndef GTK_DISABLE_DEPRECATED
-void gtk_paint_string     (GtkStyle        *style,
-                          GdkWindow       *window,
-                          GtkStateType     state_type,
-                          GdkRectangle    *area,
-                          GtkWidget       *widget,
-                          const gchar     *detail,
-                          gint             x,
-                          gint             y,
-                          const gchar     *string);
-#endif /* GTK_DISABLE_DEPRECATED */
 void gtk_paint_box        (GtkStyle        *style,
                           GdkWindow       *window,
                           GtkStateType     state_type,
@@ -799,6 +783,32 @@ void gtk_paint_layout     (GtkStyle        *style,
                            PangoLayout     *layout);
 
 
+/* --- private API --- */
+const GValue* _gtk_style_peek_property_value (GtkStyle           *style,
+                                             GType               widget_type,
+                                             GParamSpec         *pspec,
+                                             GtkRcPropertyParser parser);
+
+
+/* depprecated */
+#ifndef GTK_DISABLE_DEPRECATED
+void gtk_draw_string     (GtkStyle        *style,
+                         GdkWindow       *window,
+                         GtkStateType     state_type,
+                         gint             x,
+                         gint             y,
+                         const gchar     *string);
+void gtk_paint_string     (GtkStyle        *style,
+                          GdkWindow       *window,
+                          GtkStateType     state_type,
+                          GdkRectangle    *area,
+                          GtkWidget       *widget,
+                          const gchar     *detail,
+                          gint             x,
+                          gint             y,
+                          const gchar     *string);
+#endif /* GTK_DISABLE_DEPRECATED */
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 0b54cdfecc92bf41a099bdaf03e4079b841ca319..97e10fd458a705c75f0c6167eb492956f6f39a4d 100644 (file)
@@ -140,9 +140,7 @@ gtk_type_init (GTypeDebugFlags debug_flags)
 #include "gtktypebuiltins_ids.c"       /* type entries */
        { NULL }
       };
-      GTypeFundamentalInfo finfo = { 0, };
       GTypeInfo tinfo = { 0, };
-      GtkType type_id;
       guint i;
 
       initialized = TRUE;
index 2500432ec973323f4901f1f3084a890c644d9af5..7492e8cf82fd6ad55e86668dd6c1a6b974e5aeb7 100644 (file)
@@ -39,6 +39,7 @@
 #include "gtkprivate.h"
 #include "gdk/gdk.h"
 #include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
+#include "gobject/gvaluecollector.h"
 
 
 #define WIDGET_CLASS(w)         GTK_WIDGET_GET_CLASS (w)
@@ -191,37 +192,29 @@ static void gtk_widget_propagate_hierarchy_changed (GtkWidget *widget,
 static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
 static void             gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
 
-static gpointer parent_class = NULL;
-static guint widget_signals[LAST_SIGNAL] = { 0 };
+static gpointer         parent_class = NULL;
+static guint            widget_signals[LAST_SIGNAL] = { 0 };
 
-static GMemChunk *aux_info_mem_chunk = NULL;
-
-static GdkColormap *default_colormap = NULL;
-static GtkStyle *gtk_default_style = NULL;
-
-static GSList *colormap_stack = NULL;
-static GSList *style_stack = NULL;
-static guint   composite_child_stack = 0;
-
-static const gchar *aux_info_key = "gtk-aux-info";
-static guint        aux_info_key_id = 0;
-static const gchar *event_key = "gtk-event-mask";
-static guint        event_key_id = 0;
-static const gchar *extension_event_key = "gtk-extension-event-mode";
-static guint        extension_event_key_id = 0;
-static const gchar *parent_window_key = "gtk-parent-window";
-static guint        parent_window_key_id = 0;
-static const gchar *saved_default_style_key = "gtk-saved-default-style";
-static guint        saved_default_style_key_id = 0;
-static const gchar *shape_info_key = "gtk-shape-info";
-static const gchar *colormap_key = "gtk-colormap";
-static const gchar *pango_context_key = "gtk-pango-context";
-static guint        pango_context_key_id = 0;
+static GMemChunk       *aux_info_mem_chunk = NULL;
+static GdkColormap     *default_colormap = NULL;
+static GtkStyle        *gtk_default_style = NULL;
+static GSList          *colormap_stack = NULL;
+static GSList          *style_stack = NULL;
+static guint            composite_child_stack = 0;
+static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
+static GParamSpecPool  *style_property_spec_pool = NULL;
 
-static const gchar *rc_style_key = "gtk-rc-style";
-static guint        rc_style_key_id = 0;
+static GQuark quark_property_parser = 0;
+static GQuark quark_aux_info = 0;
+static GQuark quark_event_mask = 0;
+static GQuark quark_extension_event_mode = 0;
+static GQuark quark_parent_window = 0;
+static GQuark quark_saved_default_style = 0;
+static GQuark quark_shape_info = 0;
+static GQuark quark_colormap = 0;
+static GQuark quark_pango_context = 0;
+static GQuark quark_rc_style = 0;
 
-static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
 
 /*****************************************
  * gtk_widget_get_type:
@@ -332,6 +325,19 @@ gtk_widget_class_init (GtkWidgetClass *klass)
 
   klass->no_expose_event = NULL;
 
+  quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
+  quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
+  quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
+  quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
+  quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
+  quark_saved_default_style = g_quark_from_static_string ("gtk-saved-default-style");
+  quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
+  quark_colormap = g_quark_from_static_string ("gtk-colormap");
+  quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
+  quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
+
+  style_property_spec_pool = g_param_spec_pool_new (FALSE);
+
   gtk_object_add_arg_type ("GtkWidget::name", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NAME);
   gtk_object_add_arg_type ("GtkWidget::parent", GTK_TYPE_CONTAINER, GTK_ARG_READWRITE, ARG_PARENT);
   gtk_object_add_arg_type ("GtkWidget::x", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_X);
@@ -906,28 +912,28 @@ gtk_widget_get_arg (GtkObject   *object,
       GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
       break;
     case ARG_X:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->x;
       break;
     case ARG_Y:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->y;
       break;
     case ARG_WIDTH:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->width;
       break;
     case ARG_HEIGHT:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
@@ -964,14 +970,14 @@ gtk_widget_get_arg (GtkObject   *object,
       GTK_VALUE_BOXED (*arg) = (gpointer) gtk_widget_get_style (widget);
       break;
     case ARG_EVENTS:
-      eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+      eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
       if (!eventp)
        GTK_VALUE_FLAGS (*arg) = 0;
       else
        GTK_VALUE_FLAGS (*arg) = *eventp;
       break;
     case ARG_EXTENSION_EVENTS:
-      modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+      modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
       if (!modep)
        GTK_VALUE_FLAGS (*arg) = 0;
       else
@@ -1584,8 +1590,7 @@ gtk_widget_realize (GtkWidget *widget)
       
       if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
        {
-         shape_info = gtk_object_get_data (GTK_OBJECT (widget),
-                                           shape_info_key);
+         shape_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_shape_info);
          gdk_window_shape_combine_mask (widget->window,
                                         shape_info->shape_mask,
                                         shape_info->offset_x,
@@ -1917,7 +1922,7 @@ gtk_widget_get_child_requisition (GtkWidget        *widget,
 
   *requisition = widget->requisition;
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
   if (aux_info)
     {
       if (aux_info->width > 0)
@@ -1948,7 +1953,7 @@ gtk_widget_size_allocate (GtkWidget       *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
   real_allocation = *allocation;
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
   
   if (aux_info)
     {
@@ -3094,13 +3099,11 @@ gtk_widget_set_style (GtkWidget *widget,
   GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
   GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
 
-  default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+  default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
   if (!default_style)
     {
       gtk_style_ref (widget->style);
-      if (!saved_default_style_key_id)
-       saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_saved_default_style, widget->style);
     }
 
   gtk_widget_set_style_internal (widget, style, initial_emission);
@@ -3148,16 +3151,14 @@ gtk_widget_set_rc_style (GtkWidget *widget)
   GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
   GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
 
-  saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+  saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
   new_style = gtk_rc_get_style (widget);
   if (new_style)
     {
       if (!saved_style)
        {
          gtk_style_ref (widget->style);
-         if (!saved_default_style_key_id)
-           saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
-         gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
+         gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_saved_default_style, widget->style);
        }
       gtk_widget_set_style_internal (widget, new_style, initial_emission);
     }
@@ -3167,7 +3168,7 @@ gtk_widget_set_rc_style (GtkWidget *widget)
        {
          g_assert (initial_emission == FALSE); /* FIXME: remove this line */
 
-         gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+         gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
          gtk_widget_set_style_internal (widget, saved_style, initial_emission);
          gtk_style_unref (saved_style);
        }
@@ -3189,10 +3190,10 @@ gtk_widget_restore_default_style (GtkWidget *widget)
 
   GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
 
-  default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+  default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
   if (default_style)
     {
-      gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+      gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
       gtk_widget_set_style_internal (widget, default_style, FALSE);
       gtk_style_unref (default_style);
     }
@@ -3246,15 +3247,12 @@ gtk_widget_modify_style (GtkWidget      *widget,
 
   g_return_if_fail (GTK_IS_RC_STYLE (style));
   
-  if (!rc_style_key_id)
-    rc_style_key_id = g_quark_from_static_string (rc_style_key);
-
   old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
-                                        rc_style_key_id);
+                                        quark_rc_style);
 
   if (style != old_style)
     gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
-                                   rc_style_key_id,
+                                   quark_rc_style,
                                    gtk_rc_style_copy (style),
                                    (GtkDestroyNotify)gtk_rc_style_unref);
 
@@ -3282,17 +3280,14 @@ gtk_widget_get_modifier_style (GtkWidget      *widget)
 {
   GtkRcStyle *rc_style;
   
-  if (!rc_style_key_id)
-    rc_style_key_id = g_quark_from_static_string (rc_style_key);
-  
   rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
-                                       rc_style_key_id);
+                                       quark_rc_style);
 
   if (!rc_style)
     {
       rc_style = gtk_rc_style_new();
       gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
-                                     rc_style_key_id,
+                                     quark_rc_style,
                                      rc_style,
                                      (GtkDestroyNotify)gtk_rc_style_unref);
     }
@@ -3638,10 +3633,7 @@ gtk_widget_pop_style (void)
 static PangoContext *
 gtk_widget_peek_pango_context (GtkWidget *widget)
 {
-  if (!pango_context_key_id)
-    pango_context_key_id = g_quark_from_static_string (pango_context_key);
-
-  return gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
+  return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
 }
 
 /**
@@ -3668,15 +3660,12 @@ gtk_widget_get_pango_context (GtkWidget *widget)
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
   
-  if (!pango_context_key_id)
-    pango_context_key_id = g_quark_from_static_string (pango_context_key);
-
-  context = gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
+  context = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
   if (!context)
     {
       context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
-      gtk_object_set_data_by_id_full (GTK_OBJECT (widget), pango_context_key_id, context,
-                                     (GDestroyNotify)g_object_unref);
+      gtk_object_set_data_by_id_full (GTK_OBJECT (widget), quark_pango_context, context,
+                                     (GDestroyNotify) g_object_unref);
     }
 
   return context;
@@ -3777,7 +3766,7 @@ gtk_widget_render_icon (GtkWidget      *widget,
   
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
   g_return_val_if_fail (stock_id != NULL, NULL);
-  g_return_val_if_fail (size != NULL, NULL);
+  g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID, NULL);
   
   gtk_widget_ensure_style (widget);
   
@@ -3818,13 +3807,11 @@ gtk_widget_set_parent_window   (GtkWidget           *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
   old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
-                                                parent_window_key_id);
+                                                quark_parent_window);
 
   if (parent_window != old_parent_window)
     {
-      if (!parent_window_key_id)
-       parent_window_key_id = g_quark_from_static_string (parent_window_key);
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), parent_window_key_id, 
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_parent_window, 
                                 parent_window);
       if (old_parent_window)
        gdk_window_unref (old_parent_window);
@@ -3854,7 +3841,7 @@ gtk_widget_get_parent_window   (GtkWidget           *widget)
   g_return_val_if_fail (widget->parent != NULL, NULL);
   
   parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
-                                            parent_window_key_id);
+                                            quark_parent_window);
 
   return (parent_window != NULL) ? parent_window : widget->parent->window;
 }
@@ -3887,13 +3874,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
   if (!aux_info)
     {
-      if (!aux_info_key_id)
-       aux_info_key_id = g_quark_from_static_string (aux_info_key);
       aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
     }
 
   /* keep this in sync with gtk_window_compute_reposition() */
@@ -3945,13 +3930,11 @@ gtk_widget_set_usize (GtkWidget *widget,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
   if (!aux_info)
     {
-      if (!aux_info_key_id)
-       aux_info_key_id = g_quark_from_static_string (aux_info_key);
       aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
     }
   
   if (width > -2)
@@ -3991,7 +3974,7 @@ gtk_widget_set_events (GtkWidget *widget,
   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
   g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
   
-  eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+  eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
   
   if (events)
     {
@@ -3999,14 +3982,12 @@ gtk_widget_set_events (GtkWidget *widget,
        eventp = g_new (gint, 1);
       
       *eventp = events;
-      if (!event_key_id)
-       event_key_id = g_quark_from_static_string (event_key);
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
     }
   else if (eventp)
     {
       g_free (eventp);
-      gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
+      gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
     }
 }
 
@@ -4029,7 +4010,7 @@ gtk_widget_add_events (GtkWidget *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
   
-  eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+  eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
   
   if (events)
     {
@@ -4040,14 +4021,12 @@ gtk_widget_add_events (GtkWidget *widget,
        }
       
       *eventp |= events;
-      if (!event_key_id)
-       event_key_id = g_quark_from_static_string (event_key);
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
     }
   else if (eventp)
     {
       g_free (eventp);
-      gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
+      gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
     }
 
   if (GTK_WIDGET_REALIZED (widget))
@@ -4075,15 +4054,13 @@ gtk_widget_set_extension_events (GtkWidget *widget,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+  modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
   
   if (!modep)
     modep = g_new (GdkExtensionMode, 1);
   
   *modep = mode;
-  if (!extension_event_key_id)
-    extension_event_key_id = g_quark_from_static_string (extension_event_key);
-  gtk_object_set_data_by_id (GTK_OBJECT (widget), extension_event_key_id, modep);
+  gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode, modep);
 }
 
 /**
@@ -4166,7 +4143,7 @@ gtk_widget_get_colormap (GtkWidget *widget)
        return colormap;
     }
   
-  colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
+  colormap = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_colormap);
   if (colormap)
     return colormap;
 
@@ -4211,10 +4188,10 @@ gtk_widget_set_colormap (GtkWidget   *widget,
 
   g_object_ref (G_OBJECT (colormap));
   
-  gtk_object_set_data_full (GTK_OBJECT (widget), 
-                            colormap_key,
-                            colormap,
-                            (GtkDestroyNotify) g_object_unref);
+  g_object_set_qdata_full (G_OBJECT (widget), 
+                          quark_colormap,
+                          colormap,
+                          (GtkDestroyNotify) g_object_unref);
 }
 
 /**
@@ -4235,7 +4212,7 @@ gtk_widget_get_events (GtkWidget *widget)
   g_return_val_if_fail (widget != NULL, 0);
   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
   
-  events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+  events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
   if (events)
     return *events;
   
@@ -4259,7 +4236,7 @@ gtk_widget_get_extension_events (GtkWidget *widget)
   g_return_val_if_fail (widget != NULL, 0);
   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
   
-  mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+  mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
   if (mode)
     return *mode;
   
@@ -4641,11 +4618,11 @@ gtk_widget_real_destroy (GtkObject *object)
   gtk_grab_remove (widget);
   gtk_selection_remove_all (widget);
   
-  saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id);
+  saved_style = gtk_object_get_data_by_id (object, quark_saved_default_style);
   if (saved_style)
     {
       gtk_style_unref (saved_style);
-      gtk_object_remove_data_by_id (object, saved_default_style_key_id);
+      gtk_object_remove_data_by_id (object, quark_saved_default_style);
     }
 
   gtk_style_unref (widget->style);
@@ -4667,11 +4644,11 @@ gtk_widget_finalize (GObject *object)
   gtk_grab_remove (widget);
   gtk_selection_remove_all (widget);
 
-  saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+  saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
   if (saved_style)
     {
       gtk_style_unref (saved_style);
-      gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+      gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
     }
 
   gtk_style_unref (widget->style);
@@ -4680,15 +4657,15 @@ gtk_widget_finalize (GObject *object)
   if (widget->name)
     g_free (widget->name);
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
   if (aux_info)
     gtk_widget_aux_info_destroy (aux_info);
   
-  events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+  events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
   if (events)
     g_free (events);
   
-  mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+  mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
   if (mode)
     g_free (mode);
 
@@ -4997,15 +4974,15 @@ gtk_widget_shape_combine_mask (GtkWidget *widget,
       if (widget->window)
        gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
       
-      gtk_object_remove_data (GTK_OBJECT (widget), shape_info_key);
+      g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
     }
   else
     {
       GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
       
       shape_info = g_new (GtkWidgetShapeInfo, 1);
-      gtk_object_set_data_full (GTK_OBJECT (widget), shape_info_key, shape_info,
-                               (GDestroyNotify)gtk_widget_shape_info_destroy);
+      g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info, shape_info,
+                              (GDestroyNotify) gtk_widget_shape_info_destroy);
       
       shape_info->shape_mask = gdk_drawable_ref (shape_mask);
       shape_info->offset_x = offset_x;
@@ -5081,6 +5058,150 @@ gtk_widget_unref (GtkWidget *widget)
   g_object_unref ((GObject*) widget);
 }
 
+
+/* style properties
+ */
+
+void
+gtk_widget_class_install_style_property_parser (GtkWidgetClass     *class,
+                                               GParamSpec         *pspec,
+                                               GtkRcPropertyParser parser)
+{
+  g_return_if_fail (GTK_IS_WIDGET_CLASS (class));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (pspec->flags & G_PARAM_READABLE);
+  g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT)));
+  
+  if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE))
+    {
+      g_warning (G_STRLOC ": class `%s' already contains a style property named `%s'",
+                G_OBJECT_CLASS_NAME (class),
+                pspec->name);
+      return;
+    }
+
+  g_param_spec_ref (pspec);
+  g_param_spec_sink (pspec);
+  g_param_spec_set_qdata (pspec, quark_property_parser, parser);
+  g_param_spec_pool_insert (style_property_spec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
+}
+
+void
+gtk_widget_class_install_style_property (GtkWidgetClass *class,
+                                        GParamSpec     *pspec)
+{
+  gtk_widget_class_install_style_property_parser (class, pspec, NULL);
+}
+
+void
+gtk_widget_style_get_property (GtkWidget   *widget,
+                              const gchar *property_name,
+                              GValue      *value)
+{
+  GParamSpec *pspec;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  g_object_ref (widget);
+  pspec = g_param_spec_pool_lookup (style_property_spec_pool,
+                                   property_name,
+                                   G_OBJECT_TYPE (widget),
+                                   TRUE);
+  if (!pspec)
+    g_warning ("%s: widget class `%s' has no property named `%s'",
+              G_STRLOC,
+              G_OBJECT_TYPE_NAME (widget),
+              property_name);
+  else
+    {
+      const GValue *peek_value;
+
+      peek_value = _gtk_style_peek_property_value (widget->style,
+                                                  G_OBJECT_TYPE (widget),
+                                                  pspec,
+                                                  g_param_spec_get_qdata (pspec, quark_property_parser));
+      
+      /* auto-conversion of the caller's value type
+       */
+      if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
+       g_value_copy (peek_value, value);
+      else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
+       g_value_transform (peek_value, value);
+      else
+       g_warning ("can't retrive style property `%s' of type `%s' as value of type `%s'",
+                  pspec->name,
+                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+                  G_VALUE_TYPE_NAME (value));
+    }
+  g_object_unref (widget);
+}
+
+void
+gtk_widget_style_get_valist (GtkWidget   *widget,
+                            const gchar *first_property_name,
+                            va_list      var_args)
+{
+  const gchar *name;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  g_object_ref (widget);
+
+  name = first_property_name;
+  while (name)
+    {
+      const GValue *peek_value;
+      GParamSpec *pspec;
+      gchar *error;
+
+      pspec = g_param_spec_pool_lookup (style_property_spec_pool,
+                                       name,
+                                       G_OBJECT_TYPE (widget),
+                                       TRUE);
+      if (!pspec)
+       {
+         g_warning ("%s: widget class `%s' has no property named `%s'",
+                    G_STRLOC,
+                    G_OBJECT_TYPE_NAME (widget),
+                    name);
+         break;
+       }
+      /* style pspecs are always readable so we can spare that check here */
+
+      peek_value = _gtk_style_peek_property_value (widget->style,
+                                                  G_OBJECT_TYPE (widget),
+                                                  pspec,
+                                                  g_param_spec_get_qdata (pspec, quark_property_parser));
+      G_VALUE_LCOPY (peek_value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
+      if (error)
+       {
+         g_warning ("%s: %s", G_STRLOC, error);
+         g_free (error);
+         break;
+       }
+
+      name = va_arg (var_args, gchar*);
+    }
+
+  g_object_unref (widget);
+}
+
+void
+gtk_widget_style_get (GtkWidget   *widget,
+                     const gchar *first_property_name,
+                     ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  va_start (var_args, first_property_name);
+  gtk_widget_style_get_valist (widget, first_property_name, var_args);
+  va_end (var_args);
+}
+
 /**
  * gtk_widget_path:
  * @widget: a #GtkWidget
index 9feeb527797fb76621ce3c8cf4e42bea69081e9a..3b475e410e0ac5f9e20958fc80896400eb36c779 100644 (file)
@@ -119,18 +119,18 @@ typedef enum
  */
 #define GTK_WIDGET_SET_FLAGS(wid,flag)   G_STMT_START{ (GTK_WIDGET_FLAGS (wid) |= (flag)); }G_STMT_END
 #define GTK_WIDGET_UNSET_FLAGS(wid,flag)  G_STMT_START{ (GTK_WIDGET_FLAGS (wid) &= ~(flag)); }G_STMT_END
-  
-  
-  
-typedef struct _GtkRequisition   GtkRequisition;
-typedef struct _GdkRectangle     GtkAllocation;
-typedef struct _GtkSelectionData GtkSelectionData;
-typedef struct _GtkWidgetClass   GtkWidgetClass;
-typedef struct _GtkWidgetAuxInfo  GtkWidgetAuxInfo;
-typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
 
-typedef void (*GtkCallback) (GtkWidget *widget,
-                            gpointer   data);
+
+/* forward declaration to avoid excessive includes (and concurrent includes)
+ */
+typedef struct _GtkRequisition    GtkRequisition;
+typedef struct _GdkRectangle      GtkAllocation;
+typedef struct _GtkSelectionData   GtkSelectionData;
+typedef struct _GtkWidgetClass    GtkWidgetClass;
+typedef struct _GtkWidgetAuxInfo   GtkWidgetAuxInfo;
+typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
+typedef void     (*GtkCallback)        (GtkWidget        *widget,
+                                       gpointer          data);
 
 /* A requisition is a desired amount of space which a
  *  widget may request.
@@ -604,6 +604,24 @@ void            gtk_widget_pop_composite_child  (void);
 void        gtk_widget_pop_style            (void);
 void        gtk_widget_pop_colormap         (void);
 
+/* widget style properties
+ */
+void gtk_widget_class_install_style_property        (GtkWidgetClass     *class,
+                                                    GParamSpec         *pspec);
+void gtk_widget_class_install_style_property_parser (GtkWidgetClass     *class,
+                                                    GParamSpec         *pspec,
+                                                    GtkRcPropertyParser parser);
+void gtk_widget_style_get_property (GtkWidget       *widget,
+                                   const gchar    *property_name,
+                                   GValue           *value);
+void gtk_widget_style_get_valist   (GtkWidget       *widget,
+                                   const gchar    *first_property_name,
+                                   va_list         var_args);
+void gtk_widget_style_get          (GtkWidget       *widget,
+                                   const gchar    *first_property_name,
+                                   ...);
+
+
 /* Set certain default values to be used at widget creation time.
  */
 void        gtk_widget_set_default_style    (GtkStyle    *style);
index c4921975e6da7ad5283aa264dc2718561fd905d2..989e7b91309bc2849fef280f7cc10c104a1bd851 100644 (file)
@@ -1373,7 +1373,7 @@ gtk_window_finalize (GObject *object)
   g_free (window->wmclass_name);
   g_free (window->wmclass_class);
 
-  G_OBJECT_CLASS(parent_class)->finalize (object);
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
index 30fb41d861395926ace63ad0ebe6bab9190295ee..4abd0853d17dccffbb60639fade7574a303ac985 100644 (file)
@@ -22,14 +22,27 @@ include "testgtkrc2"
 # On Windows, if you have installed gtk-engines, try this for instance:
 #include "\\windows\\gtk\\themes\\Pixmap\\gtk\\gtkrc"
 
-#foo_number = 5
-#mouse_timeout = -7
+double-click_timeout = 42
+bell-duration = 39
+bell_duration = 40
 
 pixmap_path "."
 
+style "global-style-properties"
+{
+#  xthickness = 20
+  GtkSpinButton::shadow_type = etched-out
+}
+class "GtkWidget" style "global-style-properties"
+
 style "defaultfont"
 {
   font_name = "Sans 12"
+
+  Gtest::foo = 47
+  Gtest::bar = 47
+#  GtkScrollbar::spacing = 33
+#  GtkButton::color = { 3, 2,45, 6, 6, 4, 23 }
 }
 
 style "myicons"
index 30fb41d861395926ace63ad0ebe6bab9190295ee..4abd0853d17dccffbb60639fade7574a303ac985 100644 (file)
@@ -22,14 +22,27 @@ include "testgtkrc2"
 # On Windows, if you have installed gtk-engines, try this for instance:
 #include "\\windows\\gtk\\themes\\Pixmap\\gtk\\gtkrc"
 
-#foo_number = 5
-#mouse_timeout = -7
+double-click_timeout = 42
+bell-duration = 39
+bell_duration = 40
 
 pixmap_path "."
 
+style "global-style-properties"
+{
+#  xthickness = 20
+  GtkSpinButton::shadow_type = etched-out
+}
+class "GtkWidget" style "global-style-properties"
+
 style "defaultfont"
 {
   font_name = "Sans 12"
+
+  Gtest::foo = 47
+  Gtest::bar = 47
+#  GtkScrollbar::spacing = 33
+#  GtkButton::color = { 3, 2,45, 6, 6, 4, 23 }
 }
 
 style "myicons"